3 ms·
I feel like you could do the same thing with tuples and "splats", like in Ruby. Just wrap your values in thunks, and call it the same.
by nixpulvis 7y ago
I feel like you could do the same thing with tuples and "splats", like in Ruby. Just wrap your values in thunks, and call it the same.
- aidenn0 7y agoYou 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)
- nixpulvis 7y agoWell 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
- aidenn0 7y agoI 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.