1. feature req: passing sequences


This illustrates the problem in as little code as possible:

object junk = get_position() 
position(junk[1],junk[2]) -- this works 
position(junk)            -- this crashes 
This 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

new topic     » topic index » view message » categorize

2. Re: feature req: passing sequences

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) 
new topic     » goto parent     » topic index » view message » categorize

3. Re: feature req: passing sequences

katsmeow said...


This illustrates the problem in as little code as possible:

object junk = get_position() 
position(junk[1],junk[2]) -- this works 
position(junk)            -- this crashes 
This 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

new topic     » goto parent     » topic index » view message » categorize

4. Re: feature req: passing sequences

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**

new topic     » goto parent     » topic index » view message » categorize

5. Re: feature req: passing sequences

mattlewis said...

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.

mattlewis said...
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

new topic     » goto parent     » topic index » view message » categorize

6. Re: feature req: passing sequences


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

new topic     » goto parent     » topic index » view message » categorize

7. Re: feature req: passing sequences

katsmeow said...


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.

new topic     » goto parent     » topic index » view message » categorize

8. Re: feature req: passing sequences

katsmeow said...


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

new topic     » goto parent     » topic index » view message » categorize

9. Re: feature req: passing sequences

ryanj said...

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.

Euphoria v3.1 Reference Manual said...

... 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. blink

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

new topic     » goto parent     » topic index » view message » categorize

10. Re: feature req: passing sequences

dcuny said...

Except that you lose type safety, which is touted as one of the major features.

Euphoria v3.1 Reference Manual said...

... 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.

ex.err said...

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

new topic     » goto parent     » topic index » view message » categorize

11. Re: feature req: passing sequences

petelomax said...

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.

petelomax said...

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

new topic     » goto parent     » topic index » view message » categorize

12. Re: feature req: passing sequences

Hi

katsmeow said...


This illustrates the problem in as little code as possible:

object junk = get_position() 
position(junk[1],junk[2]) -- this works 
position(junk)            -- this crashes 
This 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

new topic     » goto parent     » topic index » view message » categorize

13. Re: feature req: passing sequences

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.

new topic     » goto parent     » topic index » view message » categorize

14. Re: feature req: passing sequences

petelomax said...

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

new topic     » goto parent     » topic index » view message » categorize

15. Re: feature req: passing sequences

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 
new topic     » goto parent     » topic index » view message » categorize

16. Re: feature req: passing sequences

cargoan said...

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.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu