1. delegate support in euphoria?
- Posted by kobi Apr 20, 2012
- 1508 views
hello, I'm a beginner, I would like to know if Euphoria supports the delegate concept, also known as: callbacks, anonymous functions.
for example, a 'retain' function filters a sequence based on a predicate (a func that returns a boolean). retain would take the sequence and the predicate as its two parameters.
now the programmer can use this construct, as an abstraction for later work that only differs by the arguments. (no need to write the same code when the "block" can be passed from outside)
2. Re: delegate support in euphoria?
- Posted by DerekParnell (admin) Apr 20, 2012
- 1494 views
hello, I'm a beginner, I would like to know if Euphoria supports the delegate concept, also known as: callbacks, anonymous functions.
for example, a 'retain' function filters a sequence based on a predicate (a func that returns a boolean). retain would take the sequence and the predicate as its two parameters.
now the programmer can use this construct, as an abstraction for later work that only differs by the arguments. (no need to write the same code when the "block" can be passed from outside)
Yes. The function routine_id() can be used to get an handle to any procedure or function and then that handle can be passed as an argument to a routine, which would call the handle's routine using either the call_func() or call_proc() as appropriate.
As an example, the custom_sort() function expects you to pass a routine_id as the comparison algorithm.
Here is an example of your 'retain' idea.
function odd_val(object X) if sequence(X) then return 0 end if if integer(X) then return and_bits(X,1) end if return 0 end function function multiple_3(object X) if sequence(X) then return 0 end if if integer(X) then return remainder(X, 3) = 0 end if return 0 end function function retain(sequence A, integer criteria) sequence temp integer p = 0 temp = repeat(0, length(A)) for i = 1 to length(A) do if call_func(criteria, {A[i]}) then p += 1 temp[p] = A[i] end if end for return temp[1.. p] end function sequence testdata = {1,2,3,4,5,6,7,8,9,10,11,12} ? retain(testdata, routine_id("odd_val")) --> {1,3,5,7,9,11} ? retain(testdata, routine_id("multiple_3")) --> {3,6,9,12}
3. Re: delegate support in euphoria?
- Posted by mattlewis (admin) Apr 20, 2012
- 1451 views
hello, I'm a beginner, I would like to know if Euphoria supports the delegate concept, also known as: callbacks, anonymous functions.
for example, a 'retain' function filters a sequence based on a predicate (a func that returns a boolean). retain would take the sequence and the predicate as its two parameters.
now the programmer can use this construct, as an abstraction for later work that only differs by the arguments. (no need to write the same code when the "block" can be passed from outside)
Yes. The function routine_id() can be used to get an handle to any procedure or function and then that handle can be passed as an argument to a routine, which would call the handle's routine using either the call_func() or call_proc() as appropriate.
There was a related thread a little while ago, talking about function composition in euphoria, which you might find interesting:
http://openeuphoria.org/forum/114817.wc
Matt
4. Re: delegate support in euphoria?
- Posted by kobi Apr 22, 2012
- 1443 views
hello, I'm a beginner, I would like to know if Euphoria supports the delegate concept, also known as: callbacks, anonymous functions.
for example, a 'retain' function filters a sequence based on a predicate (a func that returns a boolean). retain would take the sequence and the predicate as its two parameters.
now the programmer can use this construct, as an abstraction for later work that only differs by the arguments. (no need to write the same code when the "block" can be passed from outside)
Yes. The function routine_id() can be used to get an handle to any procedure or function and then that handle can be passed as an argument to a routine, which would call the handle's routine using either the call_func() or call_proc() as appropriate.
As an example, the custom_sort() function expects you to pass a routine_id as the comparison algorithm.
Here is an example of your 'retain' idea.
function odd_val(object X) if sequence(X) then return 0 end if if integer(X) then return and_bits(X,1) end if return 0 end function function multiple_3(object X) if sequence(X) then return 0 end if if integer(X) then return remainder(X, 3) = 0 end if return 0 end function function retain(sequence A, integer criteria) sequence temp integer p = 0 temp = repeat(0, length(A)) for i = 1 to length(A) do if call_func(criteria, {A[i]}) then p += 1 temp[p] = A[i] end if end for return temp[1.. p] end function sequence testdata = {1,2,3,4,5,6,7,8,9,10,11,12} ? retain(testdata, routine_id("odd_val")) --> {1,3,5,7,9,11} ? retain(testdata, routine_id("multiple_3")) --> {3,6,9,12}
Thanks! is there a benefit for initializing the sequence with repeat? (the alternative is starting with an empty sequence and appending an element every time) is the data structure (beneath the sequence) a vector, a dynamic array, some kind of tree, or a simple array that is continuously copied?
another question: is there support for 'assert' in the middle of euphoria code. thanks alot, I enjoy euphoria and appreciate your comments and support
5. Re: delegate support in euphoria?
- Posted by mattlewis (admin) Apr 22, 2012
- 1423 views
Thanks! is there a benefit for initializing the sequence with repeat? (the alternative is starting with an empty sequence and appending an element every time) is the data structure (beneath the sequence) a vector, a dynamic array, some kind of tree, or a simple array that is continuously copied?
The advantage of using repeat is that there is only a single allocation made. For relatively small sequences, this probably doesn't make much difference. When appending elements, euphoria may have to make several memory allocations, which can end up being costly. Note that it doesn't just reallocate for every element, as it usually allocates a bit extra to accommodate growth in the sequence.
A euphoria sequence is a contiguous block of memory that contains a few bytes of overhead, for bookkeeping, and the elements of the sequence. If the elements are euphoria integers, then they're simply stored in the sequence's memory. If they are atoms or sequences, then the sequence basically stores a pointer to the actual data (either a double or another sequence).
another question: is there support for 'assert' in the middle of euphoria code. thanks alot, I enjoy euphoria and appreciate your comments and support
There's no special assert function or keyword. However, you could do something like this:
-- code..... -- code... ifdef DEBUG then if some_value = 0 then crash("failed assertion that some_value != 0 ) -- NB crash() comes from std/error.e end ifdef -- more regular code
Then, when you want to run with assertions, you could do:
$ eui -d DEBUG myapp.ex
Matt
6. Re: delegate support in euphoria?
- Posted by DerekParnell (admin) Apr 22, 2012
- 1396 views
Thanks! is there a benefit for initializing the sequence with repeat? (the alternative is starting with an empty sequence and appending an element every time) is the data structure (beneath the sequence) a vector, a dynamic array, some kind of tree, or a simple array that is continuously copied?
Pre-allocating a sequence is often a good idea for performance. The append operation will usually involve allocating new memory and copying existing items.
another question: is there support for 'assert' in the middle of euphoria code. thanks alot, I enjoy euphoria and appreciate your comments and support
There isn't one supplied with the standard library but I think we should have one. Here is the sort of thing you'll need.
-- assert.e namespace assert include std/error.e ifdef assert then public procedure assert(integer x, sequence text = "") if x = 0 then crash(text) end if end procedure elsedef public procedure assert(integer x, sequence text = "") end procedure end ifdef public procedure ensure(integer x, sequence text = "") if x = 0 then crash(text) end if end procedure
You can include this file and then use the assert() routine to test your logic at run-time, but only if the 'assert' symbol has been defined on the command line. For example ...
-- mytest.ex include assert.e integer a a = 5 -- An obvious error. assert(a = 4, "'a' should be 4") ? a
When you run this normally, the assertion will not execute because the 'assert' symbol was not defined.
C:\temp> eui mytest.ex 5 C:\tempSo to get the assert() to fire, run your program with the "-d" switch ...
C:\temp>eui -d assert mytest.ex c:/Projects/eu_proj/eu40/include\std\error.e:50 in procedure crash() 'a' should be 4 ... called from C:\temp\assert.e:8 in procedure assert() ... called from C:\temp\mytest.ex:5 --> See ex.err C:\temp>
Because the assert() routine is very small, Euphoria will automatically in-line it so there is no overhead of a function call, and when the 'assert' symbol is not defined, the in-lined code is totally no-existant, thus it has no run-time performance affect.
The ensure() routine is identical to assert except that it doesn't need the 'assert' symbol to be defined. You would use ensure to ensure a condition was tested in production releases of code and use assert for tests that should not be in production releases development. This especially applies to translated programs.
7. assert in EUPHORIA
- Posted by SDPringle Apr 22, 2012
- 1417 views
For the most part, UDT makes assert obsolete. The type routine verifies the data on each change. Sometimes independent data may have some relationship that is more temporary in this case you just want to check the result of an expression that should return true. I create a type and a public variable called truth like this:
type truth_type(integer x) return x = 1 end type public truth_type truth
Then to check something I assign the expression to truth.
-- buffer should have no more nulls truth = find(0,buffer) = 0
8. Re: assert in EUPHORIA
- Posted by DerekParnell (admin) Apr 22, 2012
- 1503 views
For the most part, UDT makes assert obsolete. The type routine verifies the data on each change. Sometimes independent data may have some relationship that is more temporary in this case you just want to check the result of an expression that should return true. I create a type and a public variable called truth like this:
type truth_type(integer x) return x = 1 end type public truth_type truth
Then to check something I assign the expression to truth.
-- buffer should have no more nulls truth = find(0,buffer) = 0
Although this will perform the testing correctly, it misses out on a couple of the useful aspects of the 'assert' concept.
- It always executes the test. The assert is intended to only execute the test during the development phase of the application.
- It's crash message is obscure - type failure - whereas the assert can be given a meaningful message to display.
9. Re: assert in EUPHORIA
- Posted by petelomax Apr 23, 2012
- 1363 views
Although this will perform the testing correctly, it misses out on a couple of the useful aspects of the 'assert' concept.
- It always executes the test. The assert is intended to only execute the test during the development phase of the application.
That is what I was going to say about your assert.e; although it may not actually test whether x is 0 when "switched off", it will still calculate x, which may be expensive.
Regards, Pete
10. Re: assert in EUPHORIA
- Posted by DerekParnell (admin) Apr 23, 2012
- 1374 views
Although this will perform the testing correctly, it misses out on a couple of the useful aspects of the 'assert' concept.
- It always executes the test. The assert is intended to only execute the test during the development phase of the application.
That is what I was going to say about your assert.e; although it may not actually test whether x is 0 when "switched off", it will still calculate x, which may be expensive.
Regards, Pete
I see your point. The only way around that at the moment is to code ...
ifdef assert then assert(x) end ifdef
This is a bit more cumbersome but if you really need it then you can do it.
11. Re: assert in EUPHORIA
- Posted by jimcbrown (admin) Apr 23, 2012
- 1372 views
Although this will perform the testing correctly, it misses out on a couple of the useful aspects of the 'assert' concept.
- It always executes the test. The assert is intended to only execute the test during the development phase of the application.
That is what I was going to say about your assert.e; although it may not actually test whether x is 0 when "switched off", it will still calculate x, which may be expensive.
Regards, Pete
I can see the benefit of Shawn's idea of using a type for assertion here: when you're translating, the side-effectless type-check call is removed entirely...
I see your point. The only way around that at the moment is to code ...
ifdef assert then assert(x) end ifdef
This is a bit more cumbersome but if you really need it then you can do it.
Alternatively, you can use a preprocessor with 4.0's builtin preprocessor ability to expand all assert() calls into the longer ifdef'd form. The code will run with or without it, but with the preprocessor the full advantage of assert() comes.
12. Re: assert in EUPHORIA
- Posted by mattlewis (admin) Apr 23, 2012
- 1354 views
Although this will perform the testing correctly, it misses out on a couple of the useful aspects of the 'assert' concept.
- It always executes the test. The assert is intended to only execute the test during the development phase of the application.
That is what I was going to say about your assert.e; although it may not actually test whether x is 0 when
I can see the benefit of Shawn's idea of using a type for assertion here: when you're translating, the side-effectless type-check call is removed entirely...
I do something like this in EuSQL. You can set it to do actual error checking or just print errors (or call a user defined routine). And, of course, you can simply turn off type checking to ignore it completely.
Basically, this just handles errors coming back from the library (e.g., bad SQL, incorrect table name, etc.), so there isn't really an expensive performance hit for additional calculations. It's just a relatively simple and informative way to handle error checking.
Matt