1. delegate support in euphoria?

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)

new topic     » topic index » view message » categorize

2. Re: delegate support in euphoria?

kobi said...

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

3. Re: delegate support in euphoria?

DerekParnell said...
kobi said...

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

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

4. Re: delegate support in euphoria?

DerekParnell said...
kobi said...

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

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

5. Re: delegate support in euphoria?

kobi said...

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

kobi said...

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

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

6. Re: delegate support in euphoria?

kobi said...

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.

kobi said...

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:\temp 
So 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.

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

7. assert in EUPHORIA

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

8. Re: assert in EUPHORIA

SDPringle said...

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.

  1. It always executes the test. The assert is intended to only execute the test during the development phase of the application.
  2. It's crash message is obscure - type failure - whereas the assert can be given a meaningful message to display.
new topic     » goto parent     » topic index » view message » categorize

9. Re: assert in EUPHORIA

DerekParnell said...

Although this will perform the testing correctly, it misses out on a couple of the useful aspects of the 'assert' concept.

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

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

10. Re: assert in EUPHORIA

petelomax said...
DerekParnell said...

Although this will perform the testing correctly, it misses out on a couple of the useful aspects of the 'assert' concept.

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

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

11. Re: assert in EUPHORIA

petelomax said...
DerekParnell said...

Although this will perform the testing correctly, it misses out on a couple of the useful aspects of the 'assert' concept.

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

DerekParnell said...

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.

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

12. Re: assert in EUPHORIA

jimcbrown said...
petelomax said...
DerekParnell said...

Although this will perform the testing correctly, it misses out on a couple of the useful aspects of the 'assert' concept.

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

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

Search



Quick Links

User menu

Not signed in.

Misc Menu