1. feature req: passing sequences
- Posted by katsmeow Feb 14, 2015
- 1545 views
This illustrates the problem in as little code as possible:
object junk = get_position() position(junk[1],junk[2]) -- this works position(junk) -- this crashesThis bit me when trying to do a string execution unit too. Even though junk contains all the necessary parameters in the correct order, i cannot pass it to position(). And now it's biting at me when writing a console "gui" for my irc.e, altho in a simple way i can get around simply by typing twice as much code.
Can this situation please be changed?
Kat
2. Re: feature req: passing sequences
- Posted by DerekParnell (admin) Feb 14, 2015
- 1525 views
In the meantime, one could do this sort of thing ...
procedure set_position(object a, object b = "notatom") if integer(a) then if integer(b) then position(a,b) return end if elsif sequence (a) then if equal(b, "notatom") then if length(a) = 2 then if integer(a[1]) and integer(a[2]) then position(a[1], a[2]) return end if end if end if end if -- Garbage In end procedure object junk = get_position() set_position(junk)
3. Re: feature req: passing sequences
- Posted by mattlewis (admin) Feb 14, 2015
- 1528 views
This illustrates the problem in as little code as possible:
object junk = get_position() position(junk[1],junk[2]) -- this works position(junk) -- this crashesThis bit me when trying to do a string execution unit too. Even though junk contains all the necessary parameters in the correct order, i cannot pass it to position(). And now it's biting at me when writing a console "gui" for my irc.e, altho in a simple way i can get around simply by typing twice as much code.
Can this situation please be changed?
I've often wanted this. Obviously, it's how we pass parameters for routine id calls or the variable arguments for printf. The way to do this, I think is some sort of built in operator, let's call it param_unroll for now (it's verbose and kind of ugly, but it's obvious, so good for this discussion).
So:
position( param_unroll( junk ))
Now, what about more complicated situations?
foo( bar, param_unroll( baz ), bat, param_unroll( blat), junk )
This doesn't sound...overly difficult to implement, though probably not exactly simple once we get into the weeds. We'll need to do some temp assignments and turn those into parameters. In the interpreter at least, some additional bounds checking.
I don't think it requires any changes for the backend or even the translator. This is probably a purely front-end change (so, 100% euphoria code). Not that the front end is super simple or anything.
Although...we'll either need to go ahead and use call_func/proc or add some way to add default parameters and parameter error checking into the back end. So...maybe.
Matt
4. Re: feature req: passing sequences
- Posted by Ekhnat0n Feb 14, 2015
- 1495 views
Why not make ONE SUPERSTRUCTURE calling it as a variable type structure, name MemStruct.
The program will add each variable to it,
because the program can assign the correct space ERGO
it knows type, length and location of each variable
allowing you to call any variable by
<Value
<Ref<MemLoc(ation) and
<Name.
So no more looking for anything because your program can decide for itself
what way to deal with it.
AND by logical programming of the PROGRAMFLOW other errors/exceptionswould fall to a minimum.
THINK IT OVER**
5. Re: feature req: passing sequences
- Posted by petelomax Feb 14, 2015
- 1501 views
Now, what about more complicated situations?
foo( bar, param_unroll( baz ), bat, param_unroll( blat), junk )
Seems a little overkill to me. Would there be the problem with forcing a single unroll?
foo( param_unroll( bar & baz & bat & blat & junk ))
That might better allow re-use of some of the existing code in call_func/proc.
position( param_unroll( junk ))
Just to throw some random ideas about, maybe something a bit more minimalist like
position( @junk )
or some other [new] operator to signify desequencing, :{}junk, =:junk, :=:junk, ()junk, []junk, {}junk, to list a few possibilities.
An alternative and probably far better solution might be to make routine_id("") optional on the first parameter of call_func/proc, eg:
call_proc(position,junk)
with the bonus of seamlessly supporting those builtins for which routine_id does not currently work. Before anyone jumps the gun here, that does not mean you can actually have a routine_id for a builtin (write a tiny wrapper you lazy sod!), nor does it mean it will actually invoke call_proc/func. It would also require the routine identifier to resolve at parse-time, not run-time.
Now that I've said it I rather suspect that is much closer to what the real problem is, and you can probably forget that nonsense above about a new minimalist desequence operator?
Pete
6. Re: feature req: passing sequences
- Posted by katsmeow Feb 14, 2015
- 1461 views
The point was that get_position() gives me data i cannot pass back to position(). It's as if i do not accept dollars for payment, but i give them back as change. Like Derek said, "get_position()" and "set_position()" also work better, so i'll just wrap position() for now. But this isn't the first time or the first keyword that has bitten me like this, and if the interpreter can recieve a sequence (like position(junk)) for any keyword, know junk is a list of the params, and pass it on as params, this can be cleared up in one fell swoop for all the keywords, both built-ins and user-written.
Kat
7. Re: feature req: passing sequences
- Posted by ryanj Feb 14, 2015
- 1455 views
The point was that get_position() gives me data i cannot pass back to position(). It's as if i do not accept dollars for payment, but i give them back as change. Like Derek said, "get_position()" and "set_position()" also work better, so i'll just wrap position() for now. But this isn't the first time or the first keyword that has bitten me like this, and if the interpreter can recieve a sequence (like position(junk)) for any keyword, know junk is a list of the params, and pass it on as params, this can be cleared up in one fell swoop for all the keywords, both built-ins and user-written.
Kat
I think this is a good example of a routine that should be able to accept a sequence instead of forcing separate parameters. I run in to this problem dealing with rectangles in GUI programming. It seems to me that
position({row, column})
is better implementation than
position(integer row, integer column).
Now that i think about it, it almost seems silly that euphoria routines even have parameters instead of just passing sequences.
8. Re: feature req: passing sequences
- Posted by ghaberek (admin) Feb 14, 2015
- 1477 views
The point was that get_position() gives me data i cannot pass back to position(). It's as if i do not accept dollars for payment, but i give them back as change. Like Derek said, "get_position()" and "set_position()" also work better, so i'll just wrap position() for now. But this isn't the first time or the first keyword that has bitten me like this, and if the interpreter can recieve a sequence (like position(junk)) for any keyword, know junk is a list of the params, and pass it on as params, this can be cleared up in one fell swoop for all the keywords, both built-ins and user-written.
Kat
In this particular case, I think position(row, column) should be deprecated in favor of the more symmetrical set_position({row, column}). A "position" is always a sequence of {row,column} anyway, not two discrete values. As you put it, I don't think we should be "making change" between functions.
-Greg
9. Re: feature req: passing sequences
- Posted by dcuny Feb 14, 2015
- 1486 views
Now that i think about it, it almost seems silly that euphoria routines even have parameters instead of just passing sequences.
Except that you lose type safety, which is touted as one of the major features.
... extensive run-time checking for: out-of-bounds subscripts, uninitialized variables, bad parameter values for library routines, illegal value assigned to a variable and many more.
Odd how only "library routines" get "bad parameter values" checked.
Passing individual parameters makes it easier for the compiler to catch parameter mismatch errors.
Passing a sequence means that any problem can't be caught until runtime, which isn't optimal. Unless, of course, you've got some sort of type.
Euphoria has user-defined types, but they are also only checked at runtime - a rather odd omission.
Especially with the need to interface with libraries that support classes (such as wxWidgets), I think there's a need for Euphoria to support some sort of class system. However, it's not clear exactly how that would work, since it would need to support inheritance and polymorphism.
I've been intrigued by Typescript, because it solves a similar problem: enforcing types on on a weakly-typed language (JavaScript). The cool thing about TypeScript is that it's implemented using a pre-processor, so it outputs plain vanilla JavaScript.
I suspect that an approach like that might be a good route to take.
Sorry to hijack the thread, you just got me thinking...
- David
10. Re: feature req: passing sequences
- Posted by petelomax Feb 15, 2015
- 1429 views
Except that you lose type safety, which is touted as one of the major features.
... extensive run-time checking for
Passing individual parameters makes it easier for the compiler to catch parameter mismatch errors.
Passing a sequence means that any problem can't be caught until runtime
Hmmm. I suspect that is a common misconception. While I have added some compile-time type checking to Phix, I was not aware that OpenEuphoria had any.
without inline sequence a,b procedure doo() position(a,b) end procedure a = {1} b = {2} doo()
What I get is a run-time error, nothing whatsoever at compile-time (whereas Phix halts compilation). It just all happens so fast that you barely notice the difference.
C:\Program Files (x86)\Phix\e06.exw:4 in procedure doo() second argument of position() is not an atom ... called from C:\Program Files (x86)\Phix\e06.exw:8 Public & Export & Global & Local Variables C:\Program Files (x86)\Phix\e06.exw: a = {1} b = {2}
Anyway, I'm slowly warming to the idea that if you pass a single (sequence) parameter to a routine that expects more than one (non-optional) parameter, it could assume it must be a sequence of parameters.
There would of course be some run-time penalty, in many cases, but for get_position/position it ought to be less that manually unpicking things. It might also mean that a routine with no parameters ought to quietly accept {}, perhaps?
Pete
11. Re: feature req: passing sequences
- Posted by dcuny Feb 15, 2015
- 1415 views
Hmmm. I suspect that is a common misconception. While I have added some compile-time type checking to Phix, I was not aware that OpenEuphoria had any.
Sorry, I dropped a clause here:
If Euphoria were to pass all parameters by sequence, then all type checking of parameters within the sequence would be (obviously) deferred until runtime.
Anyway, I'm slowly warming to the idea that if you pass a single (sequence) parameter to a routine that expects more than one (non-optional) parameter, it could assume it must be a sequence of parameters.
I'm loathe to give up compile time type checking, which is why I'd rather have Euphoria explicitly support notation like this:
function foo() return 1, 2, 3 end function integer a, b, c a, b, c = foo()
rather than pack the values in to a sequence and send them merrily on their way to be unpacked by the caller:
function foo() return {1, 2, 3} end function integer a, b, c {a, b, c} = foo()
I'm not trying to argue for the comma notation at this point - just the idea that type safety is a good thing, and being able to find errors at compile time is superior to deferring to runtime. After all, the compiler is going to see all the code.
This gets back to TypeScript where the compiler tracks a lot of these details. For example, TypeScript has a interface:
interface Person { firstname: string; lastname: string; }
This is a construct that only exists at compile time. The compiler makes sure that parameters of type Person conform to the interface.
In Euphoria, the concept could be identical. Going back to the original example, you could have something like:
interface Point x integer y integer end interface
The compiler would implement all interface objects as a sequence, so behind the scenes you're still generating "classic" Euphoria code. But you get the safety of ensuring that type that's passed to the routine conforms without the overhead of having to declare a type that can only be tested at runtime.
- David
12. Re: feature req: passing sequences
- Posted by andi49 Feb 15, 2015
- 1393 views
Hi
This illustrates the problem in as little code as possible:
object junk = get_position() position(junk[1],junk[2]) -- this works position(junk) -- this crashesThis bit me when trying to do a string execution unit too. Even though junk contains all the necessary parameters in the correct order, i cannot pass it to position(). And now it's biting at me when writing a console "gui" for my irc.e, altho in a simple way i can get around simply by typing twice as much code.
Can this situation please be changed?
Kat
include std/graphics.e atom x,y puts(1,"test") {x,y}=get_position() position(x,y-2) wait_key()
This allready works in Eu4.1, or maybe i do not understand the question.
Andreas
13. Re: feature req: passing sequences
- Posted by irv Feb 15, 2015
- 1386 views
After calling x = get_position(), x is now a sequence of 2 values. So why doesn't (set) position, which seems to be the reverse operation, not accept x? Instead, it requires the programmer to break up x into 2 pieces; x[1],x[2] More work for the programmer, and just another idiosyncrasy to remember.
Symmetry is attractive both in faces and in programming languages.
14. Re: feature req: passing sequences
- Posted by mattlewis (admin) Feb 16, 2015
- 1375 views
Hmmm. I suspect that is a common misconception. While I have added some compile-time type checking to Phix, I was not aware that OpenEuphoria had any.
A little bit happens when routines are inlined:
procedure foo( sequence bar ) ? bar end procedure foo(3)
$ eui test test.ex:5 <0146>:: Type Check Error when inlining literal foo(3) ^ Press Enter
I know we've talked about doing more in this area, but no one has so far.
Matt
15. Re: feature req: passing sequences
- Posted by cargoan Feb 16, 2015
- 1339 views
object junk = get_position() position(junk[1],junk[2]) -- this works position(junk) -- this crashes
with warning save without warning &= { override } override procedure position(object row, integer column = 1) if sequence(row) then if length(row) > 1 then column = row[2] end if row = row[1] end if eu:position(row, column) end procedure with warning restore
16. Re: feature req: passing sequences
- Posted by irv Feb 16, 2015
- 1338 views
object junk = get_position() position(junk[1],junk[2]) -- this works position(junk) -- this crashes
override procedure position(object row, integer column = 1) if sequence(row) then if length(row) > 1 then column = row[2] end if row = row[1] end if eu:position(row, column) end procedure
It's not that we don't know how to patch this, the question is, shouldn't Euphoria routines be as logical as possible? IOW, if if returns a sequence, it accepts a sequence.
When there is a difference between what you receive and what you send, it just means one more thing to trip up newcomers, and one more thing for the rest of us to remember or look up. And one more thing to document.