~aliasing44


#170 Variadic arguments fail on builtin math operators 4 months ago

Comment by ~aliasing44 on ~technomancy/fennel

This macro would work, but the only problem is (= (type last) :number) doesn't cut it in terms of checking for ... or function calls -- it fires too easily, since the type of every macro argument tends to be "table".

(macro +. [...]
  (let [len (select "#" ...)
        last (select len ...)]
    (if (= (type last) :number)
        (accumulate [sum 0 i v (ipairs [...])]
          (if (> i 1) `(+ ,sum ,v) v))
        `(accumulate [sum# 0 _i# v# (ipairs ,[...])] (+ sum# v#)))))

#170 Variadic arguments fail on builtin math operators 4 months ago

Comment by ~aliasing44 on ~technomancy/fennel

[Edited because of a brain blast I had while thinking about this issue and re-reading your reply to me]

I think this can be done in a sub-optimal way without extreme difficulty.

  1. Only the last item being fed to + needs to be checked. All earlier ones are assumed to be summable.

  2. If this last item is ... or a function call, use a loop. Otherwise, just rely on the arg count to generate a sum a + b + c + etc. If the programmer really wants to optimize their adding, they can use local variables to explicitly denote the number of arguments to +. Otherwise, we get predictable DWIM lisp behavior that feels elegant.

#170 Variadic arguments fail on builtin math operators 4 months ago

Comment by ~aliasing44 on ~technomancy/fennel

I can think of a few solutions for now:

  1. Make + into a macro that sees how many arguments it's being called with, and only generate a loop if it's a variadic call, else generate x + y + z ...

  2. Make it an error to call variadic built-in operators, add new library functions fennel.sum, fennel.mul, etc. that are explicitly made in order to operate on multiple values, and suggest to use those in these edge cases.

The thing is, this is only the tip of the iceberg for weird behaviors of fennel when using the built in math operators. I can't remember what other stuff I ran into, but I'll be sure to document it.

#170 Variadic arguments fail on builtin math operators 4 months ago

Ticket created by ~aliasing44 on ~technomancy/fennel

The following functions compile in really abnormal ways:

(fn a [...] (+ ...))
(fn b [...] (- ...))
(fn c [...] (* ...))
(fn d [...] (/ ...))
(fn e [...] (% ...))
(fn f [...] (// ...))

The result I got from fennel 1.3.0 is:

local function a(...)
  return ...
end
local function b(...)
  return ( - ...)
end
local function c(...)
  return ...
end
local function d(...)
  return (1 / ...)
end
local function e(...)
  return ...
end
local function f(...)
  return (1 // ...)
end
return f

At the bare minimum, it would be helpful if this was some kind of error. Ideally, I would have these compile into some simple loops that are capable of handling things in more intuitive ways. For example, for the first one, something like:

function a(...)
  local out = 0
  for i = 1,select('#', ...) do
    out = out + select(i, ...)
  end
  return out
end

Thanks for making an awesome language, btw.