1. imp, discussions, infix, map, true, apply, eval
- Posted by Andy Kurnia <andykurn at COMP.NUS.EDU.SG> Oct 28, 1998
- 384 views
[re: imp] Carl showed how to replace imp: > if (a = 3) or not (b = 4) then... > ^^^^^^^^-imp is logical IMPlication (not obvious here) There is a more direct way, though with it you always have to evaluate both sides of the expression (even with the unreleased short-circuiting release of Euphoria): if (a = 3) <= (b = 4) then ... -- truth table: -- 1 <= 1 = 1 -- 1 <= 0 = 0 -- 0 <= 1 = 1 -- 0 <= 0 = 1 Note the reversal of the arrow -- in math, implication is =>. [re: discussions] Irv commented: > On the other hand, we got some good discussion going. > So maybe it's better sometimes not to test things very > carefully :) Somehow I agree with this statement None of the things in this mails are tested very carefully. [re: infix] Carl suggested a function infix declaration: > so that infix functions (i.e. 3 + 4 rather than +(3,4)) are possible. > > Anyway, here's some provisional syntax: > > function infix is_the_same_as(object left, object right) > return compare({a}, {b})=0 > end function Since an infix should always be a function, I am more inclined to do: infix is_the_same_as(object left, object right) return not compare(left, right) -- definitely not {a} and {b} end infix Of course, routine_id() should still allow infix functions to be called 'normally'. An alternative to this introduction of new keyword 'infix', is to allow *all* two-argument functions (and one-argument ones) to be called as operators. They are declared as functions, but both: is_the_same_as(a, b) and a is_the_same_as b are possible. All two-argument functions, when used as operators, should have equal precedence. All one-argument functions, when used as operators, should also have equal precedence. In line with Euphoria's current way of evaluating expressions, The operator precedence is thus amended as follows: calls with () (function, type) unaries (-, +, not) * unary functions used as operators multiplicative arithmetic (*, /) additive arithmetic (+, -) concatenation (&) comparison (<, >, <=, >=, =, !=) * binary functions used as operators logical binaries (and, or) short-c. formation ({, , , }) Of course, other places are possible, and it is even also possible to assign non-consecutive integers to the operators and let you designate your own level of precedence in the function declaration, somehow. Then it would be possible to do, e.g. function succ(object x) return x + 1 end function integer a a = succ succ 8; printf(1, "%d\n", {a}) -- 10 While the absence of () for one-argument functions are purely cosmetic in most cases, the absence of () for two-argument functions -- which occurs when they are called in the form of "a func b" instead of "func(a, b)" -- improves readability greatly in most cases -- if used right, that is. Then all you have to do to have a "mod" operator is: function mod(object a, object b) return remainder(a, b) -- maybe an "alias" would be nice?? end function Even without it, you can already say c = a remainder b d = a power b -- etc. [map] If comparison operators, used on a sequence, return a single boolean value instead of a sequence of its results, Ralf will complain as follows: > 3) It is in contrast with everything else we do in Euphoria: > > {1,2,3} + 1 = *a sequence* > > 5) In my opinion 'sequence' is not a datatype, it is a container. A sequence > itself is never a value, it are a number of values (atoms) that are > structured together. I agree with #5 but not with #3. If one wants such a sequence like {1,2,3} + 1, it would actually be cleaner (and probably less buggy, too) if he explicitly requests it. Therefore, I would want a built-in map function, which works roughly as follows: -- x is a function that takes in one object function map(function x, sequence y) -- can't declare 'function' for i = 1 to length(y) do y[i] = x(y[i]) end for return y end function With it, we can say map(not, x) (supposing not were a function, not a built-in). We can extend this to a multiargument map: -- x is a function that takes in as many objects as there are -- elements in y -- this function stops as soon as one list-of- -- arguments has been used up. function map(function x, sequence_of_sequences y) sequence z z = {} while not find({}, y) do z = append(z, x(y[1][1], y[2][1], y[3][1], ...)) -- ??? for i = 1 to length(y) do y[i] = y[i][2..length(y[i])] end for end while return z end function With it, we can say map(not, {x}) to achieve the above, but also map(+, {{1, 2, 3}, {6, 5, 4}}) to calculate {1, 2, 3} + {6, 5, 4}. It would be even better if map converts atom elements in y to an infinite sequence (actually, of the length of the shortest sequence in y) whose all elements are the atom itself. Thus, map(+, {{1, 2, 3}, 1}) works. If all elements are atoms, convert any one of them to a length-1 sequence before doing the other conversions (i.e. take it as 1-element sequence). The benefits of this would be: - improved readability (you know you are mapping a function to all the elements), - you can use this to map your own functions as well, - the internal implementation of built-in operators can be simplified, - etc. If you want recursion, you can implement + as e.g. function +(object a, object b) if atom(a) and atom(b) then return [+ A B] -- how-ever this is implemented internally end if return map(+, {a, b}) -- indirect recursion! end function [re: true] Ralf suggested: > 6) You could make this one function to help fix your problems, while > backwards this is not possible. > > function true (object x) > if sequence (x) then > for index = 1 to length (x) do > if not true (x) then > return 0 > end if > end for > else > return x > end if > end function > > if true ("Euphoria" = "Euphoria") then > -- Easy enough ? > end if This would fail as soon as you execute true("Euphoria" = "Eu 2.0"), since the = operator will already issue an error because "Euphoria" and "Eu 2.0" have different lengths. [apply] I wrote, in the above: > z = append(z, x(y[1][1], y[2][1], y[3][1], ...)) -- ??? Wouldn't it be easier if we have an apply function: function apply(function func, sequence args) return func(args[1], args[2], ..., args[length(args)]) end function For example, x = apply(sprintf, {1, "%s\n", {"Hello!"}}) and x = sprintf(1, "%s\n", {"Hello!"}) would be the same. The difference is that you can actually build the list of arguments yourself before you apply it to a function. [eval] Yet, a trickier approach is to be able to evaluate an Euphoria expression embedded in a string in the current context (e.g. if it modifies a variable, the variable remains modified; if it defines a function, the function remains defined) and have a value returned. It can have some statements, and at the end of it should be an expression. This expression is returned. eval should also prevent error messages, perhaps by setting a global variable or something like that instead of crashing. Examples: eval("printf(1, \"%s\\n\", {\"Hello!\"}) 3 + 4") would do the printf and return 7. eval("x = 1/0 9") would not modify x, it will return an undefined value (not 9), and it will set a global variable to state the division by zero error. puts(1, eval("integer x x = 8 \"abc \")) printf(1, "%d\n", x) will print: abc 8 With eval, we don't really need apply: x = apply(sprintf, {1, "%s\n", {"Hello!"}}) is equivalent to x = eval("sprintf(1, \"%s\\n\", {\"Hello!\"})") Comments?
2. Re: imp, discussions, infix, map, true, apply, eval
- Posted by "Carl R. White" <C.R.White at SCM.BRAD.AC.UK> Oct 29, 1998
- 382 views
> Comments? 1) I never thought someone would out-length me postwise :) 2) map()? Have you been studying Haskell? [Haskell is God awful functional language. It's unnecessarily over-recursive. Better than Prolog though <g> ] 3) I personally prefer "function infix name()...end function". It's more readable (IMHO) and easier to code ;) 4) From another post: Someone mentioned using <= for implication. I don't really like this as it implies (no pun intended) _reverse_ implication (which incidentally, I accidentally coded in my earlier post. It should have read "not a or b" rather than "a or not b". Oops.) Carl -- Carl R White -- Final Year Computer Science at the University of Bradford E-mail...: cyrek- at -bigfoot.com -- Remove the hyphens before mailing. Ta :) URL......: http://www.bigfoot.com/~cyrek/ Ykk rnyllaqur rgiokc cea nyemdok ymc giququezka caysgr -- B.Q.Vgesa