Arc Forumnew | comments | leaders | submitlogin
1 point by rocketnia 4118 days ago | link | parent

Right, things can get pretty hairy, and sometimes it won't be possible for the compiler to figure out whether a given expression will be needed unevaluated at runtime, in which case those expressions need to be preserved somewhere in the compiler's result, just in case. The preserved code could still be compiled, too, if the application's file size isn't as important as its speed, or if doing that would save from having to bundle an interpreter in there too. (Take a look at 'compose. If it's exposed in a compiled module, the code (g x) has to be preserved.)

But even for your 'pathologic example, a compiler might be able to determine that the result of the expression must be some result that one-thing could produce. That's because the 'a parameter, 'one-thing, is known at compile time to be a true value (since it's a symbol), and so both of the possible function types successfully accept two parameters and result in something 'a (one-thing) would result in when called.

This might be a bit tough for a compiler to do until it's really mature, but it does fit within the scope of a type system. In particular, the type of (if b x a y 5) might be expressible using an "if" type combinator, which I imagine can be manipulated and simplified as long as there's a way to ask a type whether its values are guaranteed to count as true or false.

More and more pathological examples could be built, though, and that's the halting problem for you.

I'm not concerned with optimization right now, more with the parsimony and elegance of the language.

As it should be. ^_^ Compiling is nothing if not one big optimization, though, so optimization was what I was talking about.

In a non-optimization defense of declare quick-syntax-transformer, it could also potentially make IDE integration slightly better, since the IDE would be able to determine more about the code being generated.

But yeah, it's not very elegant to have something in the language that programs appear to work just as well without, and it's not very parsimonious to have something in the language spec which is likely to mean nothing to lots of implementations. It's just something to keep in mind if there turns out to be a clever tweak to the language that'll help everybody.

1 point by diiq 4117 days ago | link

Compiling is nothing if not one big optimization, though, so optimization was what I was talking about.

Ah. There's our confusion. I define compiling as the transformation of code in one language to code in another (lower level) language.

Sure, Eight can be optimized. I don't see how it can (by my definition) be compiled.


1 point by rocketnia 4117 days ago | link

I was thinking about adding "(and translation)" to that sentence, but I thought that was the easy part. After all, you can just write an interpreter that compiles to the lower level language and package it up with every Eight program. It isn't an especially insightful translation, perhaps, but it's a start.


1 point by diiq 4116 days ago | link

Yes, I concede --- you're right. I should be thinking in terms of partial evaluators, rather than full compilation.

With your permission, I'd like to cp this conversation to the Eight github-wiki, so we can stop cluttering up the Arc Forum ;)


1 point by rocketnia 4115 days ago | link

Sure, that's fine by me.

Speaking of partial evaluators... I was thinking about this topic some more yesterday, in regards to my everything-is-a-multimethod language idea, and I came up with this. I imagine having

  (aif a b c d e)
translate something like this:

  (%apply %compile-to-apply '(aif a b c d e))
Here, %apply is a special value that the compiler knows will evaluate all its parameters, then apply the first parameter to the next. Meanwhile, %compile-to-apply actually breaks down the syntax passed to it so that there's a simpler %apply to execute. Since %apply, %compile-to-apply, and '(aif a b c d e) are constants, a partial evaluator can simplify this to:

  (%apply (%compiler-of aif) '(a b c d e))
Here, %compiler-of is yet another compiler-internal procedure that looks at the signature of its argument in order to produce another procedure that does the actual work of compiling a parameter list to a simpler %apply form. Since (%compiler-of aif) is usually a constant and doesn't usually have side effects, this can be evaluated some more at compile time:

  (%apply ??? a 'b '(c d e))  ; where ??? is an implementation of aif's body
Even if aif isn't a constant, as long as the compiler knows enough about what aif will be (its type), it might be able to reduce (%compiler-of aif) anyway.

Now is when (%apply ??? a 'b '(c d e)) would be inlined if possible, in the hopes of compiling '(c d e). With all of Eight's 'leak, 'comma, and 'asterix, I think that might take a few more techniques than I've thought about. My language's approach to afn would probably work a bit more like this:

  (%apply (%compiler-of aif) '(a b c d e))
  (%apply ??? (list (fn () a)
                    (fn (it) b)
                    (fn () c)
                    (fn (it) d)
                    (fn () e)))
...and therefore avoid having to working with syntax in the method body. Then again, this language is probably going to be considerably more mind-melting to try to read. Here's a generous mockup of the kind of thing I have in mind for the base language (which I'm calling Blade):

  (def (aif (-repeat branch (condition) (consequence it))
            (-optional (else) (fn ())))
    (with-first (finding-on branch
                  (= it (condition)))
      (consequence it)
      else: (else)))
I'm not sure whether you actually wanted to know any of this stuff, heh, but I hope it helps. ^_^