Hacker News new | past | comments | ask | show | jobs | submit login

You can't because in CL if you only want first return value, you can pretend that the function only returns one value.

For example, the CL integer division functions (it has each of floor, truncate, and round) all return the remainder as a second value, but you can ignore that fact if all you wanted was division:

  (floor 5 3) -> 1 ; 2

  (let ((x (floor 5 3)) x) -> 1

  (setf (values x y) (floor 5 3)) (list x y) -> (1 2)



Well seeing as I can't find an optimization in CLISP for changing the underlying div instruction, I'm assuming this is going to run the same. Is this correct?

My only point here is, I guess, that a thunk (0 argument function) acts a similar way. If we had need to call two instructions (or increase bitwidth) this might suffice:

    def floor(n, d = 1)
      [-> { n.div(d) }, -> { n.modulo(d) }]
    end

    p *floor(10.3)
    #<Proc:0x0000558aeacdbc00@s.rb:4 (lambda)>
    #<Proc:0x0000558aeacdbbd8@s.rb:4 (lambda)>

    p floor(10.3).first.call
    # 10

    p *floor(10.3).map(&:call)
    # 10
    # 0.3000000000000007


I guess my point is that multiple values are transparent; lots of times there are functions for which it's sometimes useful to have auxiliary values, but most of the time the primary value is all that is needed.

There are certainly arguments for why this might be a bad idea (if your the sort of person who likes rich type systems, you're unlikely to like this), but there is no way to do this in WASM efficiently, while there is for pretty much all real machines.

FWIW, I'm not sure about CLISP; I haven't used it for almost 20 years. Sbcl and ccl will both omit the calculation of the modulo when it is not needed. The ergonomics of a thunk or a tuple are different.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: