Skip to content

Comment on Fexl - a Function Expression Languageparent

Comments

(Intriguing suggestion about the dot operator by the way.)

On this question: "Are the atomic arithmetic operations side effects?" Not really. Well, sort of. I mean, take a look at the reduction code for adding two long values: https://github.com/chkoreff/Fexl/blob/master/src/long_add.c

In short, when you evaluate (long_add 2 3), that value is replaced with the number 5, right inside the machine data structure. So in that sense there is a "side effect", but it's a purely functional referentially transparent side effect only in the C internals -- nothing mutable going on at the Fexl level.

I'm all well-versed with CPS (continuation-passing style), e.g. I've done stuff like this:

  \do_stuff = (\state\return
      do_this state \state
      do_that state \state
      return state)
But that doesn't in itself help me, yet.

By swapping the order of the parameters "state" and "return" in do_stuff, do_this, and do_that, I can transform that function into a monadic style:

  \do_stuff = (\return
      do_this;
      do_that;
      return)
But as it turns out that accomplishes nothing essential -- it is merely a syntactic difference.

Keep in mind that Fexl is purely combinatorial, and ultimately what's really going on under the hood are the application of these two rules:

  C x y    =  x
  S x y z  =  x z; y z
So maybe that will give you some insight into just how irredeemably lazy this language really is. :)

(Yes there are some other combinators such as I, L, R, and Y, but these are ultimately shorthands for S and C forms.)

If by "interleave the add operations" you are suggesting a change to the core evaluation strategy used in the interpreter, that is probably out of the question -- I've made my bed there and I have to lie in it. There's not much I can do at this point about my reliance on combinators, I mean, check out the S combinator: https://github.com/chkoreff/Fexl/blob/master/src/S.c . That's baked in the cake!

But if you mean there's something I can do different in my Fexl function itself, that might be something to consider.

I tried the full gamut here, using both accumulator and CPS:

  \test_big_sum_4 =
  (

  \sum == (\N \total \return
      long_le N 0
          (return total)
          (sum (long_sub N 1) (long_add total N) return)
          )

  # TODO still a problem!!
  \N = 100000
  sum N 0 \total
  print "sum 1 .. "; print N; print " is "; print total;nl;
  )

  test_big_sum_4
But to no avail: it still uses up large amounts of memory.

However, I could force the evaluation of (long_sub N 1) and (long_add total N), and that might do the trick. Then it'll be totally tail recursive with machine integers at every turn, and run in constant memory.

I'm all well-versed with CPS

I'm talking about a particular application of CPS, the encoding of CBV lambda-calculus in the CBN calculus. Checkout Danvy & Filinksi (1992) if you need brushing up on this: look at what happens in your calculus when you code up the CBV version of the foldl, which should force the first atomic operation to happen before unwinding the next application of addition.

Danvy & Filinksi, 1992, Representing control: a study of the CPS transformation http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.46.8...

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.