samth
2019-6-14 12:58:13

@krismicinski it’s because I did some moves on that file


krismicinski
2019-6-14 16:21:47

yup, my bad..


sydney.lambda
2019-6-14 17:40:45

Anyone mind giving some advice regarding my attempts to add currying to a Scheme interpreter? The idea is that all of these applications should produce the same result: (f a b c d) ((((f a) b) c) d) (((f a b) c) d) ((f a b c) d) (((f a) b c) d) ... After going through a number of half-working versions, this modification to apply seems to work alright (error checking aside): (define (apply* proc actuals) (if (primop? proc) (apply proc actuals) (foldr (lambda (arg f) (let ([body (cadadr f)] [formals (caadr f)] [env (caddr f)]) (eval* body (cons (cons (car formals) arg) env)))) proc actuals))) I’d appreciate some feedback, or just thoughts in general regarding this. It seems fairly trivial (based on resources I came across) to implement this using macros, like a wrapper around all functions that counts arguments and returns either a function of lesser arguments or the result. In fact, it’s easy enough to implement curry as a plain ol’ function. However, as an exercise in aid of getting used to modifying interpreters to try out ideas, I wanted to do it this way. Thanks :slightly_smiling_face:


sydney.lambda
2019-6-14 17:42:07

(I’ve suffixed the “new” versions of eval and apply with *; Racket’s apply is used from applying primitive operations.


lexi.lambda
2019-6-14 19:19:01

@sydney.lambda If it’s truly currying you want (a la our previous discussion), I would do something like this, which essentially desugars multi-argument lambda/function application into their equivalent single-argument versions.


lexi.lambda
2019-6-14 19:30:08

@sydney.lambda Another way to do it would be to do the desugaring in a separate pass (which I’ve called expand here), so eval only has to work with a simplified core language that only has unary lambda/application.


sydney.lambda
2019-6-14 20:06:21

Thank you so much @lexi.lambda ! Thats a massive help. I especially like the second version; reducing everything down to a simplified base language is something I’m also interested in. Never would have thought to just forgo apply in this case; good to know I’m “allowed” to do that, silly as that may sound! I’ve mostly been using the “Art of the Interpreter” and SICP interpreters as reference and I’ve yet to really find my feet enough to branch away from the main blueprint too much.


lexi.lambda
2019-6-14 20:09:25

I think it’s most helpful to remember that pervasive currying means functions with arity other than 1 do not exist, so “multi-argument” lambda/application is really just syntactic sugar for nesting.


lexi.lambda
2019-6-14 20:10:28

Therefore, an interpreter for a pervasively curried language only needs to deal with unary functions, since all functions are unary functions.


sydney.lambda
2019-6-14 20:12:02

So only ((((f 1) 2) 3) 4) “really” exists, and all other ways of applying the arguments are just syntactic convenience, if I’m understanding correctly.


lexi.lambda
2019-6-14 20:12:35

Right!


lexi.lambda
2019-6-14 20:12:58

Desugaring is essentially a normalization pass.