1. Missing in misc.e

Would there ba any objections to adding (with proper documentation) the
following to misc.e:
global function abs(object x) -- absolute value
   ibject y

   if atom(x) then
      if x>=0 then
         return x
      else
         return -x
      end if
   else
      for i=1 to length(x) do
         y=x[i]
         if sequence(y) then
            x[i]=abs(y)
         elsif y<0 then
            x[i]=-y
         end if
      end for
      return x
   end if
end function

integer find_bound_mode
function find_bound(sequence s)
   integer find_max,n
   object x,y

   find_max=1-and_bits(find_bound_mode,2)
   x=s[1] -- RTFatal on s={}, that's correct
   n=1
   for i=2 to length(s) do
      y=s[i]
      if compare(y,x)=find_max then
         x=y
         n=i
      end if
   end for
   if and_bits(find_bound_mode,1) then
      return x
   else
      return n
   end if
end function
       
global function find_min(sequence s)
   find_bound_mode=2
   return find_bound(s)
end function

global function find_max(sequence s)
   find_bound_mode=0
   return find_bound(s)
end function

global function get_min(sequence s)
   find_bound_mode=3
   return find_bound(s)
end function

global function get_max(sequence s)
   find_bound_mode=1
   return find_bound(s)
end function

function min(object x,object y)
   if compare(x,y)=-1 then
      return x
   else
      return y
   end if
end function

function max(object x,object y)
   if compare(x,y)=1 then
      return x
   else
      return y
   end if
end function


why not make them standard?
Can the code be any faster?

CChris

new topic     » topic index » view message » categorize

2. Re: Missing in misc.e

CChris wrote:
> 
> Would there ba any objections to adding (with proper documentation) the
> following
> to misc.e:
> }}}
<eucode>
> global function abs(object x) -- absolute value
>    ibject y
> 
>    if atom(x) then
>       if x>=0 then
>          return x
>       else
>          return -x
>       end if
>    else
>       for i=1 to length(x) do
>          y=x[i]
>          if sequence(y) then
>             x[i]=abs(y)
>          elsif y<0 then
>             x[i]=-y
>          end if
>       end for
>       return x
>    end if
> end function
> 
> integer find_bound_mode
> function find_bound(sequence s)
>    integer find_max,n
>    object x,y
> 
>    find_max=1-and_bits(find_bound_mode,2)
>    x=s[1] -- RTFatal on s={}, that's correct
>    n=1
>    for i=2 to length(s) do
>       y=s[i]
>       if compare(y,x)=find_max then
>          x=y
>          n=i
>       end if
>    end for
>    if and_bits(find_bound_mode,1) then
>       return x
>    else
>       return n
>    end if
> end function
>        
> global function find_min(sequence s)
>    find_bound_mode=2
>    return find_bound(s)
> end function
> 
> global function find_max(sequence s)
>    find_bound_mode=0
>    return find_bound(s)
> end function
> 
> global function get_min(sequence s)
>    find_bound_mode=3
>    return find_bound(s)
> end function
> 
> global function get_max(sequence s)
>    find_bound_mode=1
>    return find_bound(s)
> end function
> 
> function min(object x,object y)
>    if compare(x,y)=-1 then
>       return x
>    else
>       return y
>    end if
> end function
> 
> function max(object x,object y)
>    if compare(x,y)=1 then
>       return x
>    else
>       return y
>    end if
> end function
> </eucode>
{{{

> 
> why not make them standard?
> Can the code be any faster?
> 
> CChris

You are going to cause name-space conflicts with code that already exists in
the archives. If you want to add code to your libraries then make them your
own. Don't add to existing general euphoria libraries.


Bernie

My files in archive:
WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API 

Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan

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

3. Re: Missing in misc.e

Bernie Ryan wrote:
> You are going to cause name-space conflicts with code that already exists in
> the archives. If you want to add code to your libraries then make them your
> own. Don't add to existing general euphoria libraries.
> 
> 
> Bernie
> 
> My files in archive:
> WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API 
> 
> Can be downloaded here:
> <a
> href="http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan">http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan</a>

I understand your concern, but how is the language supposed to grow at all? At
some point things are going to break. Especially if you add functionalities that
should already be built into the interpreter or standard libraries.

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

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

4. Re: Missing in misc.e

CChris:

It's hard for me to understand your code.
So please explain what the suggested global routines are doing, and why you
think they are useful for a considerable number of Euphoria programmers.

Regards,
   Juergen

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

5. Re: Missing in misc.e

Jason Gade wrote:
> how is the language supposed to grow at all?
Put the new code in say minmax.e instead. Far as I know there is no law 
stating that we cannot have more than 13 files in Euphoria/include.

CChris, some suggestions for you (untested):
constant FMM_MIN = 2,	-- look for min, so do compare()=-1  \ Picked so that
"1-and_bits(mode,2)"
FMM_MAX = 0,	-- look for max, so do compare()=+1  /	gives us the -1 or +1 we
need.
	 FMM_IDX = 0,	-- return idx as result
	 FMM_VAL = 1	-- return value as result
constant
	 FMM_MINIDX = FMM_MIN + FMM_IDX,
	 FMM_MINVAL = FMM_MIN + FMM_VAL,
	 FMM_MAXIDX = FMM_MAX + FMM_IDX,
	 FMM_MAXVAL = FMM_MAX + FMM_VAL

type nonmts(object s)
    if sequence(s) then
	if length(s) then return 1 end if
    end if
    return 0
end type

function find_minmax(sequence s, integer mode)
--
-- locates the largest or smallest value in s.
-- s must be a non-empty sequence.
-- mode should be one of FMM_MINIDX, FMM_MINVAL, FMM_MAXIDX, or FMM_MAXVAL
-- (see find_min/find_max/get_min/get_max)
-- eg:
--	k = find_minmax(s1,FMM_MINIDX)
--	v = find_minmax(s1,FMM_MAXVAL)
--
integer comparecode, result_idx
object result_val, this
 
    comparecode = 1-and_bits(mode,FMM_MIN)
-- ie:
--  if and_bits(mode,FMM_MIN) then
--	comparecode = -1
--  else
--	comparecode = +1
--  end if

    result_val=s[1]
    result_idx=1
    for i=2 to length(s) do
	this=s[i]
	if compare(this,result_val)=comparecode then
	    result_val=this
	    result_idx=i
	end if
    end for
    if and_bits(mode,FMM_VAL) then
	return result_val
    else
	return result_idx
    end if
end function

global function find_min(nonmts s)
-- returns the index of smallest value in s.
-- s must be a non-empty sequence.
    return find_minmax(s,FMM_MINIDX)
end function

global function find_max(nonmts s)
-- returns the index of largest value in s.
-- s must be a non-empty sequence.
    return find_minmax(s,FMM_MAXIDX)
end function

global function get_min(nonmts s)
-- returns the smallest value in s.
-- s must be a non-empty sequence.
    return find_minmax(s,FMM_MINVAL)
end function

global function get_max(nonmts s)
-- returns the largest value in s.
-- s must be a non-empty sequence.
    return find_minmax(s,FMM_MAXVAL)
end function


I don't know what an ibject is, and there is no point in adding min and max
functions to this file, unless you make them global ;-P.

Regards,
Pete

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

6. Re: Missing in misc.e

Pete Lomax wrote:
> 
> Jason Gade wrote:
> > how is the language supposed to grow at all?
> Put the new code in say minmax.e instead. Far as I know there is no law 
> stating that we cannot have more than 13 files in Euphoria/include.

Fair point.

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

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

7. Re: Missing in misc.e

Juergen Luethje wrote:
> 
> CChris:
> 
> It's hard for me to understand your code.
> So please explain what the suggested global routines are doing, and why you
> think they are useful for a considerable number of Euphoria programmers.
> 
> Regards,
>    Juergen

1/ The abs() global functions computes the absolute value of any Euphoria
object. For atoms, it takes the negative of the atom if it is less than zero,
else leaves it alone. For sequences, it applies itself to any element which is
either a sequence or an atom less than 0 (other atoms needn't be touched), and
returns the transformed sequence.

2a/ find_min(sequence s) return the position of the minimum element in s
2b/ find_max(sequence s) return the position of the maximum element in s
2c/ get_min(sequence s) return the minimum element in s
2d/ get_max(sequence s) return the maximum element in s

These 4 routines rely on a single find_bound() function using different values
for the find_bound_mode control integer. This avoids repeating code and the
number of extra tests is minimal.

Internally, find_bound() starts with the first element of s (storing it as
candidate value and 1 as candidate index), then examines in turn each other
element in increasing index order. Whenever one is found which is less than or
greater than (depending on the current find_bound_mode) than the candidate value,
its value and position are stored as candidate result. When the sequence is
exhausted, either the recorded index or value is returned, depending again on
find_bound_mode.

3a/ min(object x,object y) returns the lesser of x and y
3b/ max(object x,object y) returns the greater of x and y.

4/ In all the above, the ordering relation being used is the one defined by the
compare() Euphoria function:
a is less than b if and only if compare(a,b)=-1

5/ These functions are very basic mathematical functions which have been
rewritten over and over again, to no benefit. Whenever you study some amount of
input, it is very usual to need the extreme values. The most frequent uses are on
sequences of atoms or integers, but since the compare() function works on every
pair of Euphoria object, there is no point in restricting the types of elements
in the min/max routines; that would only add overhead for no benefit. And the
absolute unction is even more basic than this.

As a result, a considerable number of programmers is already using home brew
equivalents of some or all of these routines, and it is high time they become
standard tools, so as to avoid everyone, specially newbies, the chore of
rewriting some of them, possibly with subtle differences or bugs.

Oh, and perhaps is it worthwhile to also add the
global function sign(object x)
   if atom(x) then 
      return compare(x,0.0)
   else
      for i=1 to length(x) do
         x[i]=sign(x[i])
      end for
      return x
   end if
end function

for reasons very similar to the ones exposed in 5/ above.

HTH
CChris

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

8. Re: Missing in misc.e

Pete Lomax wrote:

> Jason Gade wrote:
>> how is the language supposed to grow at all?
> Put the new code in say minmax.e instead.

That's what I thought, too.
Then it's easy to avoid naming conflicts simply by not including this file.

<snip>

> global function get_min(nonmts s)
> -- returns the smallest value in s.
> -- s must be a non-empty sequence.
>     return find_minmax(s,FMM_MINVAL)
> end function
> 
> global function get_max(nonmts s)
> -- returns the largest value in s.
> -- s must be a non-empty sequence.
>     return find_minmax(s,FMM_MAXVAL)
> end function

The names of these functions should just be min() and max() IMHO.

Regards,
   Juergen

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

9. Re: Missing in misc.e

Pete Lomax wrote:
> 
> Jason Gade wrote:
> > how is the language supposed to grow at all?
> Put the new code in say minmax.e instead. Far as I know there is no law 
> stating that we cannot have more than 13 files in Euphoria/include.
> 

I agree with the separate minmax.e suggestion.  Didn't someone suggest
that new libraries be posted on the user contributions page so that
they could be reviewed and tested for a period of time.  I think that
is a very good idea.

Perhaps a new category could be added for proposed new features with 
say a 30-90 day test/study period to get feedback from the community.

of course posting the proposed code to this list is soliciting 
community feedback.  I think the main thing I'm suggesting is
more structure - a defined procedure.  Once again, I agree with
Jurguen's comment that a bit more organization would be good.

 community feedback.  I think the main thing I'm suggesting is
more structure - a defined procedure.  Once again, I agree with
Jurguen's comment that a bit more organization would be good.

   
> I don't know what an ibject is, and there is no point in adding min and max
> functions to this file, unless you make them global ;-P.

I don't know what an ibject is either, but for that matter
I don't know what "nomnt" stands for.  Most people probably
are able to discern the meanings and purpose of identifiers, etc
from the code. My understanding is that there is no need
to use cryptic identifiers.  

Seeing "ibject" and "nomnt" gave me a flashback to MS BASIC 2.0
on a 5k VIC-20 - that was a quarter of a century ago.

Regards,





Folding at Home: http://folding.stanford.edu/
100% MicroSoft Free
SuSE Linux 10.0
No AdWare, SpyWare, or Viruses!
Life is Good,  smile

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

10. Re: Missing in misc.e

Pete Lomax wrote:
> 
> Jason Gade wrote:
> > how is the language supposed to grow at all?
> Put the new code in say minmax.e instead. Far as I know there is no law 
> stating that we cannot have more than 13 files in Euphoria/include.
>

True. However, there is a law which says that the more places you may find
things in, the more confusion for unexperimented users. I'm not against this
split, but am not sure it is a good idea on these grounds.

Further, there are other routines to add which are about as basic and have
hardly any relationship with min/max reckoning. Which is why I initially
suggested misc.e as a natural place to look at when you are lazy enough not to
read the docs. But I don't care, as long as they make it as standard tools.
 
> CChris, some suggestions for you (untested):
> }}}
<eucode>
> constant FMM_MIN = 2,	-- look for min, so do compare()=-1  \ Picked so that
> "1-and_bits(mode,2)"
> 	 FMM_MAX = 0,	-- look for max, so do compare()=+1  /	gives us the -1 or +1 we
> need.
> 	 FMM_IDX = 0,	-- return idx as result
> 	 FMM_VAL = 1	-- return value as result
> constant
> 	 FMM_MINIDX = FMM_MIN + FMM_IDX,
> 	 FMM_MINVAL = FMM_MIN + FMM_VAL,
> 	 FMM_MAXIDX = FMM_MAX + FMM_IDX,
> 	 FMM_MAXVAL = FMM_MAX + FMM_VAL
> 

Why not, the declarations won't really hurt, but since these constants are local
to the file, why bother?

> type nonmts(object s)
>     if sequence(s) then
> 	if length(s) then return 1 end if
>     end if
>     return 0
> end type
> 

This type has no side effect and will be skipped in translated code I think. 
Isn't }}}
<eucode>return compare(s,{})=1</eucode>
{{{
 a simpler, faster implementation?

> function find_minmax(sequence s, integer mode)
> --
> -- locates the largest or smallest value in s.
> -- s must be a non-empty sequence.
> -- mode should be one of FMM_MINIDX, FMM_MINVAL, FMM_MAXIDX, or FMM_MAXVAL
> -- (see find_min/find_max/get_min/get_max)
> -- eg:
> --	k = find_minmax(s1,FMM_MINIDX)
> --	v = find_minmax(s1,FMM_MAXVAL)
> --
> integer comparecode, result_idx
> object result_val, this
>  
>     comparecode = 1-and_bits(mode,FMM_MIN)
> -- ie:
> --  if and_bits(mode,FMM_MIN) then
> --	comparecode = -1
> --  else
> --	comparecode = +1
> --  end if
> 
>     result_val=s[1]
>     result_idx=1
>     for i=2 to length(s) do
> 	this=s[i]
> 	if compare(this,result_val)=comparecode then
> 	    result_val=this
> 	    result_idx=i
> 	end if
>     end for
>     if and_bits(mode,FMM_VAL) then
> 	return result_val
>     else
> 	return result_idx
>     end if
> end function
> 
> global function find_min(nonmts s)
> -- returns the index of smallest value in s.
> -- s must be a non-empty sequence.
>     return find_minmax(s,FMM_MINIDX)
> end function
> 
> global function find_max(nonmts s)
> -- returns the index of largest value in s.
> -- s must be a non-empty sequence.
>     return find_minmax(s,FMM_MAXIDX)
> end function
> 
> global function get_min(nonmts s)
> -- returns the smallest value in s.
> -- s must be a non-empty sequence.
>     return find_minmax(s,FMM_MINVAL)
> end function
> 
> global function get_max(nonmts s)
> -- returns the largest value in s.
> -- s must be a non-empty sequence.
>     return find_minmax(s,FMM_MAXVAL)
> end function
> </eucode>
{{{


Using arguments internally isn't good for performance, since arguments are set
to no_value once on entry and once on exit of a routine. Actually I was thinking
about going exactly the other way, defining a local input_string variable,
setting it in each routine and passing no arguments to find_bound(). That's how
get.e does its thing after all..

These functions are really basic, so that one may expect them to exeute often.
That's why, contrary to my usual stand, I paid attention to as many performance
pitfalls as I could think of.

> 
> I don't know what an ibject is,

A typo on }}}
<eucode>object</eucode>
{{{
.

> and there is no point in adding min and max
> functions to this file, unless you make them global ;-P.

You have a point :P

CChris
> 
> Regards,
> Pete

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

11. Re: Missing in misc.e

Thanks for the comprehensive reply.

CChris wrote:

> Juergen Luethje wrote:
> 
>> CChris:
>> 
>> It's hard for me to understand your code.
>> So please explain what the suggested global routines are doing, and why you
>> think they are useful for a considerable number of Euphoria programmers.
>> 
>> Regards,
>>    Juergen
> 
> 1/ The abs() global functions computes the absolute value of any Euphoria
> object.
> For atoms, it takes the negative of the atom if it is less than zero, else
> leaves
> it alone. For sequences, it applies itself to any element which is either a
> sequence or an atom less than 0 (other atoms needn't be touched), and returns
> the transformed sequence.

Yes, people have repeatedly asked for this.

> 2a/ find_min(sequence s) return the position of the minimum element in s
> 2b/ find_max(sequence s) return the position of the maximum element in s

More flexible:
- find_min(sequence s, integer start)
- find_max(sequence s, integer start)

Otherwise, sooner or later we'd get additionally find_min_from() and
find_max_from(). smile

> 2c/ get_min(sequence s) return the minimum element in s
> 2d/ get_max(sequence s) return the maximum element in s

IMHO the names just should ne min() and max().

> These 4 routines rely on a single find_bound() function using different values
> for the find_bound_mode control integer. This avoids repeating code and the
> number of extra tests is minimal.
> 
> Internally, find_bound() starts with the first element of s (storing it as
> candidate
> value and 1 as candidate index), then examines in turn each other element in
> increasing index order. Whenever one is found which is less than or greater
> than (depending on the current find_bound_mode) than the candidate value, its
> value and position are stored as candidate result. When the sequence is
> exhausted,
> either the recorded index or value is returned, depending again on
> find_bound_mode.
> 
> 3a/ min(object x,object y) returns the lesser of x and y
> 3b/ max(object x,object y) returns the greater of x and y.

I think these two functions are not necessary, so we can use the names
for the really important finctions above.
If they actually are going to be implemented, then their names IMHO
should be min2() and max2() (because they compare 2 values). This is
easier to remember.

> 4/ In all the above, the ordering relation being used is the one defined by
> the compare() Euphoria function:
> a is less than b if and only if compare(a,b)=-1
> 
> 5/ These functions are very basic mathematical functions which have been
> rewritten
> over and over again, to no benefit. Whenever you study some amount of input,
> it is very usual to need the extreme values. The most frequent uses are on
> sequences
> of atoms or integers, but since the compare() function works on every pair of
> Euphoria object, there is no point in restricting the types of elements in the
> min/max routines; that would only add overhead for no benefit. And the
> absolute
> unction is even more basic than this.
> 
> As a result, a considerable number of programmers is already using home brew
> equivalents of some or all of these routines, and it is high time they become
> standard tools, so as to avoid everyone, specially newbies, the chore of
> rewriting
> some of them, possibly with subtle differences or bugs.
> 
> Oh, and perhaps is it worthwhile to also add the
> 
> global function sign(object x)
>    if atom(x) then 
>       return compare(x,0.0)
>    else
>       for i=1 to length(x) do
>          x[i]=sign(x[i])
>       end for
>       return x
>    end if
> end function
> 
> for reasons very similar to the ones exposed in 5/ above.

All this sounds reasonable to me.

To avoid naming conflicts (especially in programs that do not use these
functions anyway), the functions shouldn't be added to misc.e, but should
be in a new include file, as Pete has suggested.
E.g. min() and max() do not only apply to numbers, so e.g. minmax.e might
be a proper name. However, when the main focus is on mathematics, and whith
functions such as abs() ans sign(), then the proper name probably would
be 'math.e'. I'll actually suggest that name. Sooner or later it's good
to have a 'math.e' include file anyway, because there will come more math
stuff.

Regards,
   Juergen

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

12. Re: Missing in misc.e

Juergen Luethje wrote:
> 
> Thanks for the comprehensive reply.
> 
> CChris wrote:
> 
> > Juergen Luethje wrote:
> > 
> >> CChris:
> >> 
> >> It's hard for me to understand your code.
> >> So please explain what the suggested global routines are doing, and why you
> >> think they are useful for a considerable number of Euphoria programmers.
> >> 
> >> Regards,
> >>    Juergen
> > 
> > 1/ The abs() global functions computes the absolute value of any Euphoria
> > object.
> > For atoms, it takes the negative of the atom if it is less than zero, else
> > leaves
> > it alone. For sequences, it applies itself to any element which is either a
> > sequence or an atom less than 0 (other atoms needn't be touched), and
> > returns
> > the transformed sequence.
> 
> Yes, people have repeatedly asked for this.
> 
> > 2a/ find_min(sequence s) return the position of the minimum element in s
> > 2b/ find_max(sequence s) return the position of the maximum element in s
> 
> More flexible:
> - find_min(sequence s, integer start)
> - find_max(sequence s, integer start)
> 
> Otherwise, sooner or later we'd get additionally find_min_from() and
> find_max_from(). smile
> 

Agreed. And it has hardly any cost.

> > 2c/ get_min(sequence s) return the minimum element in s
> > 2d/ get_max(sequence s) return the maximum element in s
> 
> IMHO the names just should ne min() and max().
> 

Strange, I have _alwats_ seen min() and max() used for the two functions in 3/.
Perhaps it's a french thing, but I have my doubts. Further, get_ and find_ aren't
too difficult to figure out, are they?

> > These 4 routines rely on a single find_bound() function using different
> > values
> > for the find_bound_mode control integer. This avoids repeating code and the
> > number of extra tests is minimal.
> > 
> > Internally, find_bound() starts with the first element of s (storing it as
> > candidate
> > value and 1 as candidate index), then examines in turn each other element in
> > increasing index order. Whenever one is found which is less than or greater
> > than (depending on the current find_bound_mode) than the candidate value,
> > its
> > value and position are stored as candidate result. When the sequence is
> > exhausted,
> > either the recorded index or value is returned, depending again on
> > find_bound_mode.
> > 
> > 3a/ min(object x,object y) returns the lesser of x and y
> > 3b/ max(object x,object y) returns the greater of x and y.
> 
> I think these two functions are not necessary, so we can use the names
> for the really important finctions above.
> If they actually are going to be implemented, then their names IMHO
> should be min2() and max2() (because they compare 2 values). This is
> easier to remember.
> 

Why aren't they? I expect them to be used more, rather... Not sure everyone will
inline them, though it is obviously an option.

> > 4/ In all the above, the ordering relation being used is the one defined by
> > the compare() Euphoria function:
> > a is less than b if and only if compare(a,b)=-1
> > 
> > 5/ These functions are very basic mathematical functions which have been
> > rewritten
> > over and over again, to no benefit. Whenever you study some amount of input,
> > it is very usual to need the extreme values. The most frequent uses are on
> > sequences
> > of atoms or integers, but since the compare() function works on every pair
> > of
> > Euphoria object, there is no point in restricting the types of elements in
> > the
> > min/max routines; that would only add overhead for no benefit. And the
> > absolute
> > unction is even more basic than this.
> > 
> > As a result, a considerable number of programmers is already using home brew
> > equivalents of some or all of these routines, and it is high time they
> > become
> > standard tools, so as to avoid everyone, specially newbies, the chore of
> > rewriting
> > some of them, possibly with subtle differences or bugs.
> > 
> > Oh, and perhaps is it worthwhile to also add the
> > 
> > global function sign(object x)
> >    if atom(x) then 
> >       return compare(x,0.0)
> >    else
> >       for i=1 to length(x) do
> >          x[i]=sign(x[i])
> >       end for
> >       return x
> >    end if
> > end function
> > 
> > for reasons very similar to the ones exposed in 5/ above.
> 
> All this sounds reasonable to me.
> 
> To avoid naming conflicts (especially in programs that do not use these
> functions anyway), the functions shouldn't be added to misc.e, but should
> be in a new include file, as Pete has suggested.
> E.g. min() and max() do not only apply to numbers, so e.g. minmax.e might
> be a proper name. However, when the main focus is on mathematics, and whith
> functions such as abs() ans sign(), then the proper name probably would
> be 'math.e'. I'll actually suggest that name. Sooner or later it's good
> to have a 'math.e' include file anyway, because there will come more math
> stuff.
> 

Personally, I find it a nag to need including a file because you just need
upper() or where(). I forget it all the time. This is why splitting include files
further doesn't look to me as a very good thing - not too bad either, admittedly.
See my reply to Pete.
If defining a new include file is the way to go, then math.e looks better to me.

CChris

> Regards,
>    Juergen

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

13. Re: Missing in misc.e

CChris wrote:

> Juergen Luethje wrote:
>> 
>> Thanks for the comprehensive reply.
>> 
>> CChris wrote:

<snip>

>>> 2c/ get_min(sequence s) return the minimum element in s
>>> 2d/ get_max(sequence s) return the maximum element in s
>> 
>> IMHO the names just should ne min() and max().
>> 
> 
> Strange, I have _alwats_ seen min() and max() used for the two functions in
> 3/. Perhaps it's a french thing, but I have my doubts. Further, get_ and find_
> aren't too difficult to figure out, are they?

a) I did not say find_ should be changed. I only wrote about the prefix
   get_ in this context.
b) Starting routine names with get_ is tempting sometimes, but that can
   easily end with too many names which start with get_.
c) It's important that users easily can remember what a function does,
   when they think of its name. When there are functions max() and get_max()
it is hard to rememner which of those functions takes a sequence as
   parameter,
   and which one takes 2 objects. With functions max() and max2(), this is much
   easier, as I alredy wrote.
   
>>> These 4 routines rely on a single find_bound() function using different
>>> values
>>> for the find_bound_mode control integer. This avoids repeating code and the
>>> number of extra tests is minimal.
>>> 
>>> Internally, find_bound() starts with the first element of s (storing it as
>>> candidate
>>> value and 1 as candidate index), then examines in turn each other element in
>>> increasing index order. Whenever one is found which is less than or greater
>>> than (depending on the current find_bound_mode) than the candidate value,
>>> its
>>> value and position are stored as candidate result. When the sequence is
>>> exhausted,
>>> either the recorded index or value is returned, depending again on
>>> find_bound_mode.
>>> 
>>> 3a/ min(object x,object y) returns the lesser of x and y
>>> 3b/ max(object x,object y) returns the greater of x and y.
>> 
>> I think these two functions are not necessary, so we can use the names
>> for the really important finctions above.
>> If they actually are going to be implemented, then their names IMHO
>> should be min2() and max2() (because they compare 2 values). This is
>> easier to remember.
>> 
> 
> Why aren't they? I expect them to be used more, rather... Not sure everyone
> will inline them, though it is obviously an option.

They are not necessary, because it's so easy to write
minVal = y
if x < y then
   minVal = x
end if

And as I already wrote:
| If they actually are going to be implemented, then their names IMHO
| should be min2() and max2() (because they compare 2 values). This is
| easier to remember.

<snip>

>> To avoid naming conflicts (especially in programs that do not use these
>> functions anyway), the functions shouldn't be added to misc.e, but should
>> be in a new include file, as Pete has suggested.
>> E.g. min() and max() do not only apply to numbers, so e.g. minmax.e might
>> be a proper name. However, when the main focus is on mathematics, and whith
>> functions such as abs() ans sign(), then the proper name probably would
>> be 'math.e'. I'll actually suggest that name. Sooner or later it's good
>> to have a 'math.e' include file anyway, because there will come more math
>> stuff.
>> 
> 
> Personally, I find it a nag to need including a file because you just need
> upper()
> or where(). I forget it all the time. This is why splitting include files
> further
> doesn't look to me as a very good thing 

Nobody want's to split existing include files.
The decisive term in this context is "modularization".
Putting this stuff into "misc.e" might _unnecessarily_ cause naming conflicts,
which can easily be avoided by putting it in a separate file (as already has
been mentioned).

Also, people who don't want to remember and to write so many include file names,
can easily create a file like this:

-----------[ allinc.e ]-----------
include database.e
include dll.e
include file.e
include get.e
include graphics.e
include image.e
include machine.e
include mouse.e
include msgbox.e
include safe.e
include sort.e
include wildcard.e
include misc.e
include math.e
----------------------------------

Then in their programs people just can write:
   include allinc.e
and they are done.

Regards,
   Juergen

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

14. Re: Missing in misc.e

Juergen Luethje wrote:
> Putting this stuff into "misc.e" might _unnecessarily_ cause naming conflicts,
> which can easily be avoided by putting it in a separate file (as already has
> been mentioned).

Chris:

Check your Die Roll Scripting program in thw archive.
The include file eval.e includes misc.e and if you added
your new abs() to the misc.e file You will cause a name-space error
because your own file eval.e already contains abs(). So you would
even create a problem in your own program.

Bernie

My files in archive:
WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API 

Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan

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

15. Re: Missing in misc.e

Kenneth Rhodes wrote:

> Pete Lomax wrote:
> 
>> Jason Gade wrote:
>>> how is the language supposed to grow at all?
>> Put the new code in say minmax.e instead. Far as I know there is no law 
>> stating that we cannot have more than 13 files in Euphoria/include.
>> 
> 
> I agree with the separate minmax.e suggestion.  Didn't someone suggest
> that new libraries be posted on the user contributions page so that
> they could be reviewed and tested for a period of time.  I think that
> is a very good idea.

Thanks. Unfortunately, the number of people who explicitely said that
they support this suggestion currently is exactly 1 (= you).

> Perhaps a new category could be added for proposed new features with 
> say a 30-90 day test/study period to get feedback from the community.

Very good idea. So they will not get lost among all the other
contributions. And we should actually take the time to carefully test
and study new features. There is no reason to add new features in a
hurry.

> of course posting the proposed code to this list is soliciting 
> community feedback.  I think the main thing I'm suggesting is
> more structure - a defined procedure.  Once again, I agree with
> Jurguen's comment that a bit more organization would be good.

Without support by Rob, this would be hard to achieve ...

Regards,
   Juergen

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

16. Re: Missing in misc.e

CChris wrote:
> 
> Pete Lomax wrote:
> > Put the new code in say minmax.e instead.
> 
> True. However, 
<snip>
Distribute an allinc.e as per JL's suggestion then.

> > constant FMM_MIN = 2,
<snip>
> 
> Why not, the declarations won't really hurt, but since these constants are 
> local to the file, why bother?
They make the code far more readable.
They follow the same conventions used by all the existing standard includes, eg
see M_ALLOC etc in machine.e.
> 
> > type nonmts(object s)
As someone else noted, that should probably be non_empty_sequence().
> >     if sequence(s) then
> > 	   if length(s) then return 1 end if
> >     end if
> >     return 0
> > end type
> > 
> 
> This type has no side effect and will be skipped in translated code I 
> think.
What exactly do you mean by that? I gather that is technically true, but I fail
to see any reason why you would suddenly say that...
> 
> Isn't }}}
<eucode>return compare(s,{})=1</eucode>
{{{
 a simpler, faster 
> implementation?
HUH??!! <scratches head> Oh, I see now, but I would comment it:
type non_empty_sequence(object s)
integer c
    c = compare(s,{})
    -- c is now -1 if s is an atom,
    --           0 if s is {},
    --          +1 if s is sequence of length 1 or more.
    return c=1
end type


<SNIP>
> Using arguments internally isn't good for performance, since arguments are 
> set to no_value once on entry and once on exit of a routine. Actually I 
> was thinking about going exactly the other way, defining a local 
> input_string variable, setting it in each routine and passing no arguments 
> to find_bound().

Chris, there is a limit. Next you'll be stripping all comments and whitespace to
shave 3 nanoseconds off load time. For better performance you would implement
these as new opcodes instead of Eu code anyway. Also I suspect the and_bits()
calls add at least 4 times what parameters would.
What timing tests have you run, if any, and what actual results does your above
mentioned change actually gain?

> That's how get.e does its thing after all..
Not really for the same reason, rather to avoid having to pass the string to
Get(), get_number(), get_string(), get_qchar(), skip_blanks(), and getch().

Regards,
Pete

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

17. Re: Missing in misc.e

Juergen Luethje wrote:
> They are not necessary, because it's so easy to write
> }}}
<eucode>
> minVal = y
> if x < y then
>    minVal = x
> end if
> </eucode>
{{{

False. I use min and max all the time:
C:\Program Files\Edita\eacca.e:95  baseline=Min(selY,CursorY)
C:\Program Files\Edita\eacolor.ew:427  y=Max(MAXnColours-4,18)*20+95
C:\Program Files\Edita\eacolor.ew:522  y+=Max(0,16-MAXnColours)*20+40
C:\Program Files\Edita\eaerror.ew:258	  pukkaWidth=Max(dX+30,200)   -- set
initial width
C:\Program Files\Edita\eamisc.e:53 global function Min(integer a, integer b)
C:\Program Files\Edita\eamisc.e:58 global function Max(integer a, integer b)
C:\Program Files\Edita\eaqj.ew:83  setIndex(ROUTINELIST, Min(ind+5,tally))
C:\Program Files\Edita\easynld.e:573	  bracelevel=Min(ch-'0',7)
C:\Program Files\Edita\eaundo.ew:269	   mY=Min(selY,CursorY)
C:\Program Files\Edita\eaundo.ew:270	   mX=Min(selX,CursorX)
C:\Program Files\Edita\eaundo.ew:286	    CursorX=Min(selX,CursorX)
C:\Program Files\Edita\edita.exw:964 
paintRqd=Min(paintRqd,Min(linefrom,lineto))
C:\Program Files\Edita\edita.exw:966	 
paintLast=Max(paintLast,Max(linefrom,lineto))
C:\Program Files\Edita\edita.exw:969  paintRqd=Min(linefrom,lineto)
C:\Program Files\Edita\edita.exw:970  paintLast=Max(linefrom,lineto)
C:\Program Files\Edita\edita.exw:2711	  for idx = Min(ixFrom,ixTo) to
Max(ixFrom,ixTo) do
C:\Program Files\Edita\edita.exw:3355	     CursorY=Min(selY,CursorY)
C:\Program Files\Edita\edita.exw:3356	     cX=Min(selX,CursorX)
C:\Program Files\Edita\edita.exw:3374	cY=Min(selY,CursorY)
C:\Program Files\Edita\edita.exw:3375	cX=Min(selX,CursorX)
C:\Program Files\Edita\edita.exw:3376	sX=Max(selX,CursorX)
C:\Program Files\Edita\edita.exw:4699	    CursorY =
Min(adjustLine(CursorY,+linesPerPage,CursorX),filelen-1)
C:\Program Files\Edita\edita.exw:5112	   newY =
Min(adjustLine(TopLine,linesPerPage-1,TopChunk),length(filetext[currfile])-1)
C:\Program Files\Edita\edita.exw:5244	    CursorY =
Min(length(filetext[currfile])-1,
C:\Program Files\Edita\edita.exw:5248	    CursorY =
Min(adjustLine(TopLine,floor((y-ClipRect[2])/CharHeight),TopChunk),
C:\Program Files\Edita\edita.exw:5281	    CursorX =
Min(Column+floor((x-ClipRect[1]-foldMargin)/CharWidth),
C:\Program Files\Edita\edita.exw:5383	     
Min(Column+floor((x-ClipRect[1])/CharWidth),
C:\Program Files\Edita\edita.exw:5385	     
Min(adjustLine(TopLine,floor((y-ClipRect[2])/CharHeight),TopChunk),
C:\Program Files\Edita\edita.exw:6914	   CursorY =
Min(adjustLine(TopLine,screenY,CursorX),length(filetext[currfile])-1)
C:\Program Files\Edita\edita.exw:6918 --      CursorY =
Min(adjustLine(CursorY,+linesPerPage,CursorX),filelen-1)


> And as I already wrote:
> | If they actually are going to be implemented, then their names IMHO
> | should be min2() and max2() (because they compare 2 values). This is
> | easier to remember.
> 
For me it is pretty ingrained that min() takes two parameters and returns the
smaller. Finding the smallest element of an arbitrary length list is a much rarer
thing, and even rarer still to want the value not the idx IMHO.

Regards,
Pete

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

18. Re: Missing in misc.e

Pete Lomax wrote:

> Juergen Luethje wrote:
>>
>> They are not necessary, because it's so easy to write
>> 
>> minVal = y
>> if x < y then
>>    minVal = x
>> end if
>> 
> False. I use min and max all the time:
> C:\Program Files\Edita\eacca.e:95  baseline=Min(selY,CursorY)
> C:\Program Files\Edita\eacolor.ew:427  y=Max(MAXnColours-4,18)*20+95
> C:\Program Files\Edita\eacolor.ew:522  y+=Max(0,16-MAXnColours)*20+40
> C:\Program Files\Edita\eaerror.ew:258	  pukkaWidth=Max(dX+30,200)   -- set
> initial
> width
> C:\Program Files\Edita\eamisc.e:53 global function Min(integer a, integer b)
> C:\Program Files\Edita\eamisc.e:58 global function Max(integer a, integer b)
> C:\Program Files\Edita\eaqj.ew:83  setIndex(ROUTINELIST, Min(ind+5,tally))
> C:\Program Files\Edita\easynld.e:573	  bracelevel=Min(ch-'0',7)
> C:\Program Files\Edita\eaundo.ew:269	   mY=Min(selY,CursorY)
> C:\Program Files\Edita\eaundo.ew:270	   mX=Min(selX,CursorX)
> C:\Program Files\Edita\eaundo.ew:286	    CursorX=Min(selX,CursorX)
> C:\Program Files\Edita\edita.exw:964 
> paintRqd=Min(paintRqd,Min(linefrom,lineto))
> C:\Program Files\Edita\edita.exw:966	 
> paintLast=Max(paintLast,Max(linefrom,lineto))
> C:\Program Files\Edita\edita.exw:969  paintRqd=Min(linefrom,lineto)
> C:\Program Files\Edita\edita.exw:970  paintLast=Max(linefrom,lineto)
> C:\Program Files\Edita\edita.exw:2711	  for idx = Min(ixFrom,ixTo) to
> Max(ixFrom,ixTo)
> do
> C:\Program Files\Edita\edita.exw:3355	     CursorY=Min(selY,CursorY)
> C:\Program Files\Edita\edita.exw:3356	     cX=Min(selX,CursorX)
> C:\Program Files\Edita\edita.exw:3374	cY=Min(selY,CursorY)
> C:\Program Files\Edita\edita.exw:3375	cX=Min(selX,CursorX)
> C:\Program Files\Edita\edita.exw:3376	sX=Max(selX,CursorX)
> C:\Program Files\Edita\edita.exw:4699	    CursorY =
> Min(adjustLine(CursorY,+linesPerPage,CursorX),filelen-1)
> C:\Program Files\Edita\edita.exw:5112	   newY =
> Min(adjustLine(TopLine,linesPerPage-1,TopChunk),length(filetext[currfile])-1)
> C:\Program Files\Edita\edita.exw:5244	    CursorY =
> Min(length(filetext[currfile])-1,
> C:\Program Files\Edita\edita.exw:5248	    CursorY =
> Min(adjustLine(TopLine,floor((y-ClipRect[2])/CharHeight),TopChunk),
> C:\Program Files\Edita\edita.exw:5281	    CursorX =
> Min(Column+floor((x-ClipRect[1]-foldMargin)/CharWidth),
> C:\Program Files\Edita\edita.exw:5383	     
> Min(Column+floor((x-ClipRect[1])/CharWidth),
> C:\Program Files\Edita\edita.exw:5385	     
> Min(adjustLine(TopLine,floor((y-ClipRect[2])/CharHeight),TopChunk),
> C:\Program Files\Edita\edita.exw:6914	   CursorY =
> Min(adjustLine(TopLine,screenY,CursorX),length(filetext[currfile])-1)
> C:\Program Files\Edita\edita.exw:6918 --      CursorY =
> Min(adjustLine(CursorY,+linesPerPage,CursorX),filelen-1)
> 
> 
>> And as I already wrote:
>> | If they actually are going to be implemented, then their names IMHO
>> | should be min2() and max2() (because they compare 2 values). This is
>> | easier to remember.
>> 
> For me it is pretty ingrained that min() takes two parameters and returns the
> smaller. Finding the smallest element of an arbitrary length list is a much
> rarer thing,

Not for me.
Also, of course finding the smallest element of a list is the general
principle, and finding the smallest of 2 given values is a special case.
This means:
a) A special function
      x = mini2(a,b)
   is not necessary, because always the general function can be used instead:
      x = min({a,b})  

b) If the special functions that take 2 parameters actually are going to
   be implemented, then their names should be min2() and max2() (because
   they compare 2 objects) -- or something similar. The general function 
   that takess a sequence as parameter should have the general name 'min'.

And, quoting myself:
| c) It's important that users easily can remember what a function does,
|   when they think of its name. When there are functions max() and get_max()
|   it is hard to rememner which of those functions takes a sequence as
parameter,
|   and which one takes 2 objects. With functions max() and max2(), this is much
|   easier.

Regards,
   Juergen

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

19. Re: Missing in misc.e

Juergen Luethje wrote:
> Not for me.
> Also, of course finding the smallest element of a list is the general
> principle, and finding the smallest of 2 given values is a special case.
> This means:
> a) A special function
>       x = mini2(a,b)
>    is not necessary, because always the general function can be used instead:
>       x = min({a,b})  

If this works, then you wouldn't need two different functions, would you? That
seems pretty elegant to me. (Note: I haven't tried to implement it).


--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

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

20. Re: Missing in misc.e

Jason Gade wrote:

> Juergen Luethje wrote:
> > Not for me.
> > Also, of course finding the smallest element of a list is the general
> > principle, and finding the smallest of 2 given values is a special case.
> > This means:
> > a) A special function
> >       x = mini2(a,b)
> >    is not necessary, because always the general function can be used
> >    instead:
> >       x = min({a,b})  
> 
> If this works, then you wouldn't need two different functions, would you?

No, we do not need two differnet min() ( or max(), respectively ) functions.
That's what I wanted to say.

> That seems pretty elegant to me.

That's Euphoria-like, isn't it? smile

> (Note: I haven't tried to implement it).

Implementation:
global function min (sequence s)
   object x

   x = s[1]
   for i = 2 to length(s) do
      if x > s[i] then
         x = s[i]
      end if
   end for
   return x
end function

Regards,
   Juergen

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

21. Re: Missing in misc.e

Pete Lomax wrote:
> 
> CChris wrote:
> > 
> > Pete Lomax wrote:
> > > Put the new code in say minmax.e instead.
> > 
> > True. However, 
> <snip>
> Distribute an allinc.e as per JL's suggestion then.
> 

Why not have a new standard include file, say standard.e, containing only
include statements to all the other standard files? That's what I eventually did.
For production code, this extra layer can be dismissed, as only the truly needed
include files need be mentioned, but it's handy during development.

> > > constant FMM_MIN = 2,
> <snip>
> > 
> > Why not, the declarations won't really hurt, but since these constants are 
> > local to the file, why bother?
> They make the code far more readable.
> They follow the same conventions used by all the existing standard includes,
> eg see M_ALLOC etc in machine.e.

These ar global, which is why I don't think the above is as much necessary -
user never has the ability to input these mode values. But it's ok.

> > 
> > > type nonmts(object s)
> As someone else noted, that should probably be non_empty_sequence().
> > >     if sequence(s) then
> > > 	   if length(s) then return 1 end if
> > >     end if
> > >     return 0
> > > end type
> > > 
> > 
> > This type has no side effect and will be skipped in translated code I 
> > think.
> What exactly do you mean by that? I gather that is technically true, but I
> fail
> to see any reason why you would suddenly say that...

Because the type suddenly popped up smile
More seriously, I mean that it is hardly useful - calling the min/max functions
doesn't make sense -, and anyway the x=s[1], or whatever it gets renamed to, will
error out at a reasonable place. And futehr it won't even be used when
translated. All in all, useless code.

> > 
> > Isn't }}}
<eucode>return compare(s,{})=1</eucode>
{{{
 a simpler, faster 
> > implementation?
> HUH??!! <scratches head> Oh, I see now, but I would comment it:
> }}}
<eucode>
> type non_empty_sequence(object s)
> integer c
>     c = compare(s,{})
>     -- c is now -1 if s is an atom,
>     --           0 if s is {},
>     --          +1 if s is sequence of length 1 or more.
>     return c=1
> end type
> </eucode>
{{{

> 

Are all/most standard files commented to that level? There's a limit...

> <SNIP>
> > Using arguments internally isn't good for performance, since arguments are 
> > set to no_value once on entry and once on exit of a routine. Actually I 
> > was thinking about going exactly the other way, defining a local 
> > input_string variable, setting it in each routine and passing no arguments 
> > to find_bound().
> 
> Chris, there is a limit. Next you'll be stripping all comments and whitespace
> to shave 3 nanoseconds off load time.

I never suggested this sort of thing. Quite the contrary. The only limit is that
too many comments kill comments - hardly anyone will read them. Plus load time
matters only for either very large programs/libs, or time critical stuff you'd be
better off writing in C or asm anyway. Utilities need to be fast, since they are
supposed to execute often, possibly inside loops.

 For better performance you would implement
> these as new opcodes instead of Eu code anyway. 

Not at all. If I suggested them as external stuff, it is *because* they wouldn't
gain much by being opcodes.

> Also I suspect the and_bits()
> calls add at least 4 times what parameters would.

The call supposed to eventually resolve to and al,2 / neg al / inc al, so I
don't see why you say that. But I now see that I can get rid of the middle
instructions by changing the sign and the order of arguments in the main
compare(). Thanks for the implied suggestion.

> What timing tests have you run, if any, and what actual results does your
> above
> mentioned change actually gain?
> 

And yes, I'll run some benchmarks on various versions and post the results
- with/without arguments, with an and_bits() or an explicit if conversion, etc.
This weekend I'd say. Perhaps the summary might help if confirmed on several
different machines, by being included in relnotes.htm, in the performance tips
section. Even if the end result is that the variants hardly make a difference.

> > That's how get.e does its thing after all..
> Not really for the same reason, rather to avoid having to pass the string to
> Get(), get_number(), get_string(), get_qchar(), skip_blanks(), and getch().
> 

Well it is exactly the same reason, except that the impact will be less, as
there is no recursion here.

> Regards,
> Pete

CChris

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

22. Re: Missing in misc.e

Jason Gade wrote:
> 
> Juergen Luethje wrote:
> > Not for me.
> > Also, of course finding the smallest element of a list is the general
> > principle, and finding the smallest of 2 given values is a special case.
> > This means:
> > a) A special function
> >       x = mini2(a,b)
> >    is not necessary, because always the general function can be used
> >    instead:
> >       x = min({a,b})  
> 
> If this works, then you wouldn't need two different functions, would you? That
> seems pretty elegant to me. (Note: I haven't tried to implement it).
> 

Not elegant, as the curly braces are not needed.
Confusing, because the min() notation to compare two objects is so universal.

If we could overload symbols, ie having different routines share the same name
with different signatures, because they do the same thing to different sorts or
forms of arguments, then both might be called min() or max() for more
convenience. But I doubt this will be ever possible in Eu because it is weakly
typed.

CChris

> 
> --
> "Any programming problem can be solved by adding a level of indirection."
> --anonymous
> "Any performance problem can be solved by removing a level of indirection."
> --M. Haertel
> "Premature optimization is the root of all evil in programming."
> --C.A.R. Hoare
> j.

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

23. Re: Missing in misc.e

CChris wrote:
> 
> Jason Gade wrote:
> > 
> > Juergen Luethje wrote:
> > > Not for me.
> > > Also, of course finding the smallest element of a list is the general
> > > principle, and finding the smallest of 2 given values is a special case.
> > > This means:
> > > a) A special function
> > >       x = mini2(a,b)
> > >    is not necessary, because always the general function can be used
> > >    instead:
> > >       x = min({a,b})  
> > 
> > If this works, then you wouldn't need two different functions, would you?
> > That
> > seems pretty elegant to me. (Note: I haven't tried to implement it).
> > 
> 
> Not elegant, as the curly braces are not needed.
> Confusing, because the min() notation to compare two objects is so universal.
> 
> If we could overload symbols, ie having different routines share the same name

Don't you dare! ( smile )

Chris

> with different signatures, because they do the same thing to different sorts
> or forms of arguments, then both might be called min() or max() for more
> convenience.
> But I doubt this will be ever possible in Eu because it is weakly typed.
> 
> CChris
> 
> > 
> > --
> > "Any programming problem can be solved by adding a level of indirection."
> > --anonymous
> > "Any performance problem can be solved by removing a level of indirection."
> > --M. Haertel
> > "Premature optimization is the root of all evil in programming."
> > --C.A.R. Hoare
> > j.

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

24. Re: Missing in misc.e

CChris wrote:
> 
> Pete Lomax wrote:
> > Distribute an allinc.e as per JL's suggestion then.
> > 
> 
> Why not have a new standard include file, say standard.e, containing only
> include
> statements to all the other standard files? That's what I eventually did. 
That is exactly what I meant. I don't care what you call it.

> For production code, this extra layer can be dismissed, as only the truly >
> needed include files need be mentioned, but it's handy during development.
Unnecessary. AFIAK, extra levels of include nesting have zero impact on
production code, except perhaps the .exe might be say 80 bytes bigger since a
file table somewhere now has a "standard.e" entry for ex.err.

> > eg see M_ALLOC etc in machine.e.
> 
> These are global
FYI, they are not.

> > > > type non_empty_sequence(object s)
> > > This type has no side effect and will be skipped in translated code I 
> > > think.
> > What exactly do you mean by that? I gather that is technically true, but 
> > I fail to see any reason why you would suddenly say that...
> 
> anyway the x=s[1], or whatever it gets renamed to, will error out at a 
> reasonable place. And futehr it won't even be used when translated. All in 
> all, useless code.
If I get a typecheck error on the function min() statement, then I know the
problem is with the parameters I passed. If I get a subscript out of bounds error
5 lines into the routine body, I will assume there is a bug in the standard
include file.

I suggested this use of a type to follow the convention used by all the existing
standard include files.

> Are all/most standard files commented to that level? There's a limit...
Touche.

Regards,
Pete

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

25. Re: Missing in misc.e

CChris wrote:
> 
> Not elegant, as the curly braces are not needed.
> Confusing, because the min() notation to compare two objects is so universal.
> 
> If we could overload symbols, ie having different routines share the same name
> with different signatures, because they do the same thing to different sorts
> or forms of arguments, then both might be called min() or max() for more
> convenience.
> But I doubt this will be ever possible in Eu because it is weakly typed.
> 
> CChris

I still think it's elegant. Why have two functions that do the exact same thing?
In fact, I'd write it to return an index as well:

global function min(sequence s)
    object x
    integer index

    x = s[1]
    for i = 2 to length(s) do
        if x > s[i] then
            x = s[i]
            index = i
        end if
    end for

return {x, index} -- depending on what is of more interest this order could
    be swapped

end function


Implement max() similarly or use one function with a flag value as you did
somewhere up above.

Personally, I prefer weak-typing.

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

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

26. Re: Missing in misc.e

Jason Gade wrote:
> 
> CChris wrote:
> > 
> > Not elegant, as the curly braces are not needed.
> > Confusing, because the min() notation to compare two objects is so
> > universal.
> > 
> > If we could overload symbols, ie having different routines share the same
> > name
> > with different signatures, because they do the same thing to different sorts
> > or forms of arguments, then both might be called min() or max() for more
> > convenience.
> > But I doubt this will be ever possible in Eu because it is weakly typed.
> > 
> > CChris
> 
> I still think it's elegant. Why have two functions that do the exact same
> thing?
> In fact, I'd write it to return an index as well:
> 
> }}}
<eucode>
> global function min(sequence s)
>     object x
>     integer index
> 
>     x = s[1]
>     for i = 2 to length(s) do
>         if x > s[i] then
>             x = s[i]
>             index = i
>         end if
>     end for
> 
>     return {x, index} -- depending on what is of more interest this order
>     could be swapped
> 
> end function
> </eucode>
{{{

> 
> Implement max() similarly or use one function with a flag value as you did
> somewhere
> up above.
> 
> Personally, I prefer weak-typing.
> 
> --
> "Any programming problem can be solved by adding a level of indirection."
> --anonymous
> "Any performance problem can be solved by removing a level of indirection."
> --M. Haertel
> "Premature optimization is the root of all evil in programming."
> --C.A.R. Hoare
> j.
Ack! I just copied Juergen's implementation from above and that might not work
(atom expected...)

Which kind of gets back to an earlier discussion.

global function min(sequence s)
    object x
    integer index
 
    x = s[1]
    for i = 2 to length(s) do
        if compare(x, s[i]) = 1 then
            x = s[i]
            index = i
        end if
    end for
 
return {x, index} -- depending on what is of more interest this order could
   be swapped

end function


--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

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

27. Re: Missing in misc.e

OK, here's a single min() function that does the three things it ought to.
CChris may need medical assistance after seeing how many tests I just put in.
constant GREATER = 1,
	 LESS = -1

sequence s	    -- non empty sequence to find min/max in.
object sfrom, sto   -- as passed or 1 & length(s).
integer relation    -- GREATER or LESS required from compare().
integer return_idx  -- if non-0 return idx, else return value.

function min_or_max()
-- internal routine
object x
integer index

    x = s[sfrom]
    index = sfrom
    for i = sfrom+1 to sto do
	if compare(s[i], x) = relation then
	    x = s[i]
	    index = i
	end if
    end for
    if return_idx then
	return index
    end if
    return x
end function

constant MM_SEQ = #01,
	 MM_VAL = 0,
	 MM_IDX = #02

global constant MM_PAIR = 0,
		MM_SEQVAL = MM_SEQ,
		MM_SEQIDX = MM_SEQ+MM_IDX

procedure Abort(sequence msg) puts(1,msg) ?9/0 end procedure

global function min(object a, object b, object mode)
-- returns the minimum of a pair of values, or the minimum in a sequence.
-- mode must be one of:
--	MM_PAIR (=0) - return the minimum of two values passed in a & b
--	 (if mode is not 0 then parameter b is unused and must be 0)
--	MM_SEQVAL     - return the minimum value in sequence a
--	MM_SEQIDX   - return the index of ""
-- if mode is a sequence of length 3, the first must be MM_SEQVAL/IDX,
--  and the second and third elements indicate the start and end points.
--
-- examples:
--	?min(3.5,5.5,0) 		    -- prints 3.5
--	?min(13.5,5.5,0)		    -- prints 5.5
--	?max(13.5,5.5,0)		    -- prints 13.5
--	?max(3.5,5.5,0) 		    -- prints 5.5
--	?min({1,3,5,7},0,MM_SEQVAL)	    -- prints 1
--	?min({1,3,5,7},0,{MM_SEQVAL,2,3})   -- prints 3
--	?max({1,3,5,7},0,{MM_SEQVAL,2,3})   -- prints 5
--	?max({1,3,5,7},0,MM_SEQVAL)	    -- prints 7
--	?min({1,3,5,7},0,MM_SEQIDX)	    -- prints 1
--	?min({1,3,5,7},0,{MM_SEQIDX,2,3})   -- prints 2
--	?max({1,3,5,7},0,{MM_SEQIDX,2,3})   -- prints 3
--	?max({1,3,5,7},0,MM_SEQIDX)	    -- prints 4

    if equal(mode,MM_PAIR) then
	if compare(a,b)<0 then return a end if return b
    elsif not equal(b,0) then
	Abort("parameter b must be 0 for mode MM_SEQ")
    elsif compare(a,{})<1 then
	Abort("parameter a must be sequence of length >=1 for mode MM_SEQ")
    end if
    if sequence(mode) then
	if length(mode)!=3 then
	    Abort("third parameter to min() must be a sequence of length 3")
	end if
	sfrom = mode[2]
	if not integer(sfrom) or sfrom<1 or sfrom>length(a) then
	    Abort("start point parameter out of bounds")
	end if
	sto = mode[3]
	if not integer(sto) or sto<sfrom then
	    Abort("end point parameter out of bounds")
	end if
	mode = mode[1]
    else
	sfrom = 1
	sto = length(a)
    end if
    if not and_bits(mode,MM_SEQ) then
	Abort("mode MM_SEQ expected")
    end if
    return_idx = and_bits(mode,MM_IDX)
    relation = LESS
    s = a
    return min_or_max()
end function

global function max(object a, object b, object mode)
-- returns the maximum of a pair of values, or the maximum in a sequence.
-- mode must be one of:
--	MM_PAIR (=0) - return the maximum of two values passed in a & b
--	 (if mode is not 0 then parameter b is unused and must be 0)
--	MM_SEQVAL   - return the maximum value in sequence a
--	MM_SEQIDX   - return the index of ""
-- if mode is a sequence of length 3, the first must be MM_SEQVAL/IDX,
--  and the second and third elements indicate the start and end points.
--
-- examples:
--	?min(3.5,5.5,0) 		    -- prints 3.5
--	?min(13.5,5.5,0)		    -- prints 5.5
--	?max(13.5,5.5,0)		    -- prints 13.5
--	?max(3.5,5.5,0) 		    -- prints 5.5
--	?min({1,3,5,7},0,MM_SEQVAL)	    -- prints 1
--	?min({1,3,5,7},0,{MM_SEQVAL,2,3})   -- prints 3
--	?max({1,3,5,7},0,{MM_SEQVAL,2,3})   -- prints 5
--	?max({1,3,5,7},0,MM_SEQVAL)	    -- prints 7
--	?min({1,3,5,7},0,MM_SEQIDX)	    -- prints 1
--	?min({1,3,5,7},0,{MM_SEQIDX,2,3})   -- prints 2
--	?max({1,3,5,7},0,{MM_SEQIDX,2,3})   -- prints 3
--	?max({1,3,5,7},0,MM_SEQIDX)	    -- prints 4

    if equal(mode,MM_PAIR) then
	if compare(a,b)>0 then return a end if return b
    elsif not equal(b,0) then
	Abort("parameter b must be 0 for mode MM_SEQ")
    elsif compare(a,{})<1 then
	Abort("parameter a must be sequence of length >=1 for mode MM_SEQ")
    end if
    if sequence(mode) then
	if length(mode)!=3 then
	    Abort("third parameter to max() must be a sequence of length 3")
	end if
	sfrom = mode[2]
	if not integer(sfrom) or sfrom<1 or sfrom>length(a) then
	    Abort("start point parameter out of bounds")
	end if
	sto = mode[3]
	if not integer(sto) or sto<sfrom then
	    Abort("end point parameter out of bounds")
	end if
	mode = mode[1]
    else
	sfrom = 1
	sto = length(a)
    end if
    if not and_bits(mode,MM_SEQ) then
	Abort("mode MM_SEQ expected")
    end if
    return_idx = and_bits(mode,MM_IDX)
    relation = GREATER
    s = a
    return min_or_max()
end function


Regards,
Pete

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

28. Re: Missing in misc.e

Pete Lomax wrote:
> 
> 
> OK, here's a single min() function that does the three things it ought to.
> CChris may need medical assistance after seeing how many tests I just put in.
> }}}
<eucode>
> constant GREATER = 1,
> 	 LESS = -1
> 
> sequence s	    -- non empty sequence to find min/max in.
> object sfrom, sto   -- as passed or 1 & length(s).
> integer relation    -- GREATER or LESS required from compare().
> integer return_idx  -- if non-0 return idx, else return value.
> 
> function min_or_max()
> -- internal routine
> object x
> integer index
> 
>     x = s[sfrom]
>     index = sfrom
>     for i = sfrom+1 to sto do
> 	if compare(s[i], x) = relation then
> 	    x = s[i]
> 	    index = i
> 	end if
>     end for
>     if return_idx then
> 	return index
>     end if
>     return x
> end function
> 
> constant MM_SEQ = #01,
> 	 MM_VAL = 0,
> 	 MM_IDX = #02
> 
> global constant MM_PAIR = 0,
> 		MM_SEQVAL = MM_SEQ,
> 		MM_SEQIDX = MM_SEQ+MM_IDX
> 
> procedure Abort(sequence msg) puts(1,msg) ?9/0 end procedure
> 
> global function min(object a, object b, object mode)
> -- returns the minimum of a pair of values, or the minimum in a sequence.
> -- mode must be one of:
> --	MM_PAIR (=0) - return the minimum of two values passed in a & b
> --	 (if mode is not 0 then parameter b is unused and must be 0)
> --	MM_SEQVAL     - return the minimum value in sequence a
> --	MM_SEQIDX   - return the index of ""
> -- if mode is a sequence of length 3, the first must be MM_SEQVAL/IDX,
> --  and the second and third elements indicate the start and end points.
> --
> -- examples:
> --	?min(3.5,5.5,0) 		    -- prints 3.5
> --	?min(13.5,5.5,0)		    -- prints 5.5
> --	?max(13.5,5.5,0)		    -- prints 13.5
> --	?max(3.5,5.5,0) 		    -- prints 5.5
> --	?min({1,3,5,7},0,MM_SEQVAL)	    -- prints 1
> --	?min({1,3,5,7},0,{MM_SEQVAL,2,3})   -- prints 3
> --	?max({1,3,5,7},0,{MM_SEQVAL,2,3})   -- prints 5
> --	?max({1,3,5,7},0,MM_SEQVAL)	    -- prints 7
> --	?min({1,3,5,7},0,MM_SEQIDX)	    -- prints 1
> --	?min({1,3,5,7},0,{MM_SEQIDX,2,3})   -- prints 2
> --	?max({1,3,5,7},0,{MM_SEQIDX,2,3})   -- prints 3
> --	?max({1,3,5,7},0,MM_SEQIDX)	    -- prints 4
> 
>     if equal(mode,MM_PAIR) then
> 	if compare(a,b)<0 then return a end if return b
>     elsif not equal(b,0) then
> 	Abort("parameter b must be 0 for mode MM_SEQ")
>     elsif compare(a,{})<1 then
> 	Abort("parameter a must be sequence of length >=1 for mode MM_SEQ")
>     end if
>     if sequence(mode) then
> 	if length(mode)!=3 then
> 	    Abort("third parameter to min() must be a sequence of length 3")
> 	end if
> 	sfrom = mode[2]
> 	if not integer(sfrom) or sfrom<1 or sfrom>length(a) then
> 	    Abort("start point parameter out of bounds")
> 	end if
> 	sto = mode[3]
> 	if not integer(sto) or sto<sfrom then
> 	    Abort("end point parameter out of bounds")
> 	end if
> 	mode = mode[1]
>     else
> 	sfrom = 1
> 	sto = length(a)
>     end if
>     if not and_bits(mode,MM_SEQ) then
> 	Abort("mode MM_SEQ expected")
>     end if
>     return_idx = and_bits(mode,MM_IDX)
>     relation = LESS
>     s = a
>     return min_or_max()
> end function
> 
> global function max(object a, object b, object mode)
> -- returns the maximum of a pair of values, or the maximum in a sequence.
> -- mode must be one of:
> --	MM_PAIR (=0) - return the maximum of two values passed in a & b
> --	 (if mode is not 0 then parameter b is unused and must be 0)
> --	MM_SEQVAL   - return the maximum value in sequence a
> --	MM_SEQIDX   - return the index of ""
> -- if mode is a sequence of length 3, the first must be MM_SEQVAL/IDX,
> --  and the second and third elements indicate the start and end points.
> --
> -- examples:
> --	?min(3.5,5.5,0) 		    -- prints 3.5
> --	?min(13.5,5.5,0)		    -- prints 5.5
> --	?max(13.5,5.5,0)		    -- prints 13.5
> --	?max(3.5,5.5,0) 		    -- prints 5.5
> --	?min({1,3,5,7},0,MM_SEQVAL)	    -- prints 1
> --	?min({1,3,5,7},0,{MM_SEQVAL,2,3})   -- prints 3
> --	?max({1,3,5,7},0,{MM_SEQVAL,2,3})   -- prints 5
> --	?max({1,3,5,7},0,MM_SEQVAL)	    -- prints 7
> --	?min({1,3,5,7},0,MM_SEQIDX)	    -- prints 1
> --	?min({1,3,5,7},0,{MM_SEQIDX,2,3})   -- prints 2
> --	?max({1,3,5,7},0,{MM_SEQIDX,2,3})   -- prints 3
> --	?max({1,3,5,7},0,MM_SEQIDX)	    -- prints 4
> 
>     if equal(mode,MM_PAIR) then
> 	if compare(a,b)>0 then return a end if return b
>     elsif not equal(b,0) then
> 	Abort("parameter b must be 0 for mode MM_SEQ")
>     elsif compare(a,{})<1 then
> 	Abort("parameter a must be sequence of length >=1 for mode MM_SEQ")
>     end if
>     if sequence(mode) then
> 	if length(mode)!=3 then
> 	    Abort("third parameter to max() must be a sequence of length 3")
> 	end if
> 	sfrom = mode[2]
> 	if not integer(sfrom) or sfrom<1 or sfrom>length(a) then
> 	    Abort("start point parameter out of bounds")
> 	end if
> 	sto = mode[3]
> 	if not integer(sto) or sto<sfrom then
> 	    Abort("end point parameter out of bounds")
> 	end if
> 	mode = mode[1]
>     else
> 	sfrom = 1
> 	sto = length(a)
>     end if
>     if not and_bits(mode,MM_SEQ) then
> 	Abort("mode MM_SEQ expected")
>     end if
>     return_idx = and_bits(mode,MM_IDX)
>     relation = GREATER
>     s = a
>     return min_or_max()
> end function
> </eucode>
{{{

> 
> Regards,
> Pete

I don't know if you ever heard about the Shadoks, a "new look" (for the time)
french cartoon of the late 60s. One of their great thoughts was "Why make it
simple since we can make it more complicated?".

CChris

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

29. Re: Missing in misc.e

CChris wrote:
> 
<snip>
> global function sign(object x)
>    if atom(x) then 
>       return compare(x,0.0)
>    else
>       for i=1 to length(x) do
        x[i]=sign(x[i])----------error------------
>       end for
>       return x
>    end if
> end function
> </eucode>
{{{

> for reasons very similar to the ones exposed in 5/ above.
> 
> HTH
> CChris


Hello CChris,

    You can't do this, can you?
    Call a function the middle of that function?

Don Cole

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

30. Re: Missing in misc.e

don cole wrote:
> 
> CChris wrote:
> > 
> <snip>
> > global function sign(object x)
> >    if atom(x) then 
> >       return compare(x,0.0)
> >    else
> >       for i=1 to length(x) do
>         x[i]=sign(x[i])----------error------------
> >       end for
> >       return x
> >    end if
> > end function
> > </eucode>
{{{

> > for reasons very similar to the ones exposed in 5/ above.
> > 
> > HTH
> > CChris
> 
> 
> Hello CChris,
> 
>     You can't do this, can you?
>     Call a function the middle of that function?
> 
> Don Cole

Of course you can. It's called recursion and it is very common in programming.
In fact, it's a key concept of mathematics and computer science.

http://en.wikipedia.org/wiki/Recursion_%28computer_science%29

The classic example is finding the factorial of a number:

function factorial(integer f)
    if f = 1 then
        return 1
    else
        return f * factorial(f - 1)
    end if
end function


It's not always the most efficient, but sometimes it's the best.




--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

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

31. Re: Missing in misc.e

don cole wrote:
> 
> CChris wrote:
> > 
> <snip>
> > global function sign(object x)
> >    if atom(x) then 
> >       return compare(x,0.0)
> >    else
> >       for i=1 to length(x) do
>         x[i]=sign(x[i])----------error------------
> >       end for
> >       return x
> >    end if
> > end function
> > </eucode>
{{{

> > for reasons very similar to the ones exposed in 5/ above.
> > 
> > HTH
> > CChris
> 
> 
> Hello CChris,
> 
>     You can't do this, can you?
>     Call a function the middle of that function?
> 
> Don Cole

Well... not only I can, but it does what I expect!

CChris

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

32. Re: Missing in misc.e

don cole wrote:
> > global function sign(object x)
>         x[i]=sign(x[i])----------error------------
> > end function
> Hello CChris,
> 
>     You can't do this, can you?
>     Call a function the middle of that function?
C'mon Don.
You know this.
It is called recursion.
In get.e, Get() calls Get().
In file.e, walk_dir() calls walk_dir().
In misc.e, pretty_print(), rPrint() calls rPrint().

Recursion is a very common and very powerful technique.

Pete

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

33. Re: Missing in misc.e

Of course, an element of a sequence can also be a sequence, which is another
form of recursion, albeit data rather than code, but any code which handles such
data must (or at least very probably is) also recursive.

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

34. Re: Missing in misc.e

CChris wrote:
> 
> Pete Lomax wrote:
> > 
> > here's a single min() function that does the three things it ought to.
<SNIP>
> I don't know if you ever heard about the Shadoks cartoon. One of their 
> great thoughts was "Why make it simple since we can make it more 
> complicated?".
No, I never heard of that. Frankly, I am surprised that you like it since I
thought you might have a problem with the relatively large number of tests needed
to make the simple interface work blink I look forward to seeing how it fares in
this weekends bench tests.

Regards,
Pete

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

35. Re: Missing in misc.e

Pete Lomax wrote:
> 
> CChris wrote:
> > 
> > Pete Lomax wrote:
> > > 
> > > here's a single min() function that does the three things it ought to.
> <SNIP>
> > I don't know if you ever heard about the Shadoks cartoon. One of their 
> > great thoughts was "Why make it simple since we can make it more 
> > complicated?".
> No, I never heard of that. Frankly, I am surprised that you like it since I
> thought you might have a problem with the relatively large number of tests
> needed
> to make the simple interface work blink I look forward to seeing how it fares
> in this weekends bench tests.
> 
> Regards,
> Pete

Heh, I thought that it was a bit complicated too. I'm all for consolidating, but
sometimes too much is too much.

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

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

36. Re: Missing in misc.e

I'll start benchmarking later today hopefully, but here is a new version of the
min/max part of say math.e, taking into account some of the earlier discussion:

global constant  FB_MIN = 0,
                 FB_MAX = 8,
                 FB_INDEX = 1,
                 FB_VALUE = 2,
                 FB_PAIR = 4
constant M_CRASH_MESSAGE = 37,
         FB_ALT_MIN=1,
         FB_ALT_MAX=-1

integer find_max, starting_point,return_mode
sequence fb_seq
function find_bound()
   object min_or_max,y

   if starting_point > length(fb_seq) or starting_point < 1 then
       machine_proc(M_CRASH_MESSAGE,
         "math.e: Cannot find bounds of an empty sequence.")
       ?1/0 -- force run time error
   end if
   min_or_max=fb_seq[starting_point]
   for i=starting_point+1 to length(fb_seq) do
      y=fb_seq[i]
      if compare(min_or_max,y)=find_max then
         min_or_max=y
         starting_point=i
      end if
   end for
   if and_bits(return_mode, FB_PAIR) then
       if and_bits(return_mode,FB_INDEX) then
           return {starting_point,min_or_max}
       else
           return {min_or_max,starting_point}
       end if
   elsif and_bits(return_mode,FB_INDEX) then
      return starting_point
   else
      return min_or_max
   end if      
end function
       
global function find_min(sequence s,integer start)
   find_bound_mode=FB_ALT_MIN
   return_mode=FB_INDEX
   fb_seq = s
   starting_point = start
   return find_bound()
end function

global function find_max(sequence s,integer start)
   find_max=FB_ALT_MAX
   return_mode=FB_INDEX
   starting_point = start
   fb_seq = s
   return find_bound()
end function

global function get_min(sequence s,integer start)
   find_alt_max = FB_ALT_MIN
   return_mode=FB_VALUE
   starting_point = start
   fb_seq = s
   return find_bound()
end function

global function get_max(sequence s,integer start)
   find_bound_mode=FB_ALT_MAX
   return_mode=FB_VALUE
   starting_point = start
   fb_seq = s
   return find_bound()
end function

global function find_sequence_bounds(sequence s,integer start,integer mode)
    return_mode=and_bits(mode,FB_INDEX+FB_VALUE+FB_PAIR)
    if not return_mode then
        machine_proc(M_CRASH_MESSAGE,
          "math.e: find_sequence_bounds() doesn not know what to return.")
        ?1/0
    end if
    if and_bits(mode,FB_MAX) then
        find_bound_mode=FB_ALT_MAX
    else
        find_bound_mode=FB_ALT_MIN
    end if
    starting_point = start
    fb_seq=s
    return find_bound()
end function

function min(object x,object y)
   if compare(x,y)=-1 then
      return x
   else
      return y
   end if
end function

function max(object x,object y)
   if compare(x,y)=1 then
      return x
   else
      return y
   end if
end function


The basic idea is that you can have speed by using canned forms, or flexibility
using the general form, but not both at the same time. And it is not fair to
force a specific choice on the coder or the user.

I don't like the double test on return from find_bounds(), I'll see if I can
optimise it - or if it just doesn't matter anyway. After all, it's the only place
there's always a test, so it may be acceptable.

CChris

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

37. Re: Missing in misc.e

By the way: I am not strongly against a new math.e include file, but does it
make sense that arcsin() and friends remain in misc.e while abs(), sign() and
friends would go to another file? I don't think it does. Just put the few math
routines in misc.e, just like now. Or move arcsin() and friends to math.e.

CChris

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

38. Re: Missing in misc.e

CChris wrote:
> Would there be any objections to adding (with proper documentation)
> the following to misc.e:

Well I might as well submit my versions too blink

The first file is my 'assert' implementation.

-- assert.e
include misc.e

--: Parameters:
--:   pA = Any value
--:   pB = Any value
--:   pName = Displayable name to identify this assert if it fails.
--: Description: If pA and pB are not equal, this routine displays
--:     a message identifying the assert test and then aborts the program.
--:
--: Example:
--:    assert(sqrt(4), 2, "sqrt test")
--:    assert(isSaved, 0, "File should not be saved yet.")
--:    assert(fileType, "exw", "Only 'exw' is allowed")

global procedure assert(object pA, object pB, sequence pName)
    if compare(pA, pB) != 0 then
        printf(2, "Assert error '%s'\n", {pName})
        puts(2, "** First argument ...\n")
        pretty_print(2, pA, {2})
        puts(2, "\n** Second argument ...\n")
        pretty_print(2, pB, {2})
        ? 1/0
    end if
end procedure



Now here is my math.e library. I wrote this after seeing the contributions so
far.

-- math.e
constant vUnitTesting = find("-unittest", command_line())
include assert.e as assert

--: Return: The absolute value of the argument.
--: Parameters:
--:   pData = The data whose absolute value is returned.
--: Description: When the argument is a sequence, each element is made absolute,
and
--: this is done recursively to each sub-sequence as well.
--: Example:
--:    abs(3) returns 3
--:    abs(-3) returns 3
--:    abs(3.21) returns 3.21
--:    abs(-3.21) returns 3.21
--:    abs({1,-2,3,-4}) returns {1,2,3,4}
--:    abs({1,-2,{3.1,-3.2,-3.3},-4}) returns {1,2,{3.1,3.2,3.3},4}

---------------------------------------------------------
global function abs(object pData)
---------------------------------------------------------
    object lTemp

    if atom(pData) then
        if pData >= 0 then
            return pData
        end if
        return -pData
    end if

    for i = 1 to length(pData) do
        lTemp = pData[i]
        if atom(lTemp) then
            if lTemp < 0 then
                pData[i] = -lTemp
            end if
        else
            pData[i] = abs(lTemp)
        end if
    end for

    return pData
end function
if vUnitTesting then
    assert:assert(abs(0), 0, "abs0")
    assert:assert(abs(3), 3, "abs1")
    assert:assert(abs(-3),  3, "abs2")
    assert:assert(abs(3.21),  3.21, "abs3")
    assert:assert(abs(-3.21),  3.21, "abs4")
    assert:assert(abs({1,-2,3,-4}),  {1,2,3,4}, "abs5")
assert:assert(abs({1,-2,{3.1,-3.2,-3.3},-4}),  {1,2,{3.1,3.2,3.3},4},
    "abs6")
end if

--: Return: The sign of the argument. -1 means negative, 1 means positive.
--:     Note that zero is deemed as positive.
--: Parameters:
--:   pData = The data whose sign is returned.
--: Description: When the argument is a sequence, the sign of each element
--:     is set, and this is done recursively to each sub-sequence as well.
--: Example:
--:    sign(3) returns 1
--:    sign(-3) returns -1
--:    sign(3.21) returns 1
--:    sign(-3.21) returns -1
--:    sign({1,-2,3,-4}) returns {1,-1,1,-1}
--:    sign({1,-2,{3.1,-3.2,-3.3},-4}) returns {1,-1,{1,-1,-1},-1}

---------------------------------------------------------
global function sign(object pData)
---------------------------------------------------------
    object lTemp

    if atom(pData) then
        if pData >= 0 then
            return 1
        end if
        return -1
    end if

    for i = 1 to length(pData) do
        lTemp = pData[i]
        if atom(lTemp) then
            if lTemp < 0 then
                pData[i] = -1
            else
                pData[i] = 1
            end if
        else
            pData[i] = sign(lTemp)
        end if
    end for

    return pData
end function
if vUnitTesting then
    assert:assert(sign(0), 1, "sign0")
    assert:assert(sign(3), 1, "sign1")
    assert:assert(sign(-3),  -1, "sign2")
    assert:assert(sign(3.21),  1, "sign3")
    assert:assert(sign(-3.21),  -1, "sign4")
    assert:assert(sign({1,-2,3,-4}),  {1,-1,1,-1}, "sign5")
assert:assert(sign({1,-2,{3.1,-3.2,-3.3},-4}),  {1,-1,{1,-1,-1},-1},
    "sign6")
end if

--: Return: The element with the lowest value
--: Parameters:
--:   pList = A list of one or more items to examine.
--: Description: The elements of the list are compared to each other
--:   and the one with the lowest value is returned.
--:
--:   This does not do a recursive compare on sub-sequences.
--:
--:   An empty sequence will cause a runtime error.
--:
--: Example:
--:    min({1,-2, 3.1,-3.2,-3.3,-4}) returns -4
--:    min({"one", "two", "three", "four"}) returns "four"

---------------------------------------------------------
global function min(sequence pList)
---------------------------------------------------------
    object lResult

    lResult = pList[1]
    for i = 2 to length(pList) do
        if compare(lResult, pList[i]) = 1 then
            lResult = pList[i]
        end if
    end for

    return lResult
end function
if vUnitTesting then
    assert:assert(min({1}), 1, "min1")
    assert:assert(min({1,-2, 3.1,-3.2,-3.3,-4}), -4, "min_AB")
    assert:assert(min({"one", "two", "three", "four"}), "four", "min3")
end if

--: Return: The element with the highest value
--: Parameters:
--:   pList = A list of one or more items to examine.
--: Description: The elements of the list are compared to each other
--:   and the one with the highest value is returned.
--:
--:   This does not do a recursive compare on sub-sequences.
--:
--:   An empty sequence will cause a runtime error.
--:
--: Example:
--:    max({1,-2, 3.1,-3.2,-3.3,-4}) returns 3.1
--:    max({"one", "two", "three", "four"}) returns "two"

---------------------------------------------------------
global function max(sequence pList)
---------------------------------------------------------
    object lResult

    lResult = pList[1]
    for i = 2 to length(pList) do
        if compare(lResult, pList[i]) = -1 then
            lResult = pList[i]
        end if
    end for

    return lResult
end function
if vUnitTesting then
    assert:assert(max({1}), 1, "max1")
    assert:assert(max({1,-2, 3.1,-3.2,-3.3,-4}), 3.1, "max_AB")
    assert:assert(max({"one", "two", "three", "four"}), "two", "max3")
end if


--: Return: The index to the element with the lowest value
--: Parameters:
--:   pList = A list of one or more items to examine.
--: Description: The elements of the list are compared to each other
--:   and the index to one with the lowest value is returned.
--:
--:   This does not do a recursive compare on sub-sequences.
--:
--:   An empty sequence will cause a runtime error.
--:
--: Example:
--:    min_index({1,-2, 3.1,-3.2,-3.3,-4}) returns 6
--:    min_index({"one", "two", "three", "four"}) returns 4

---------------------------------------------------------
global function min_index(sequence pList)
---------------------------------------------------------
    object lTemp
    integer lPos

    lTemp = pList[1]
    lPos = 1
    for i = 2 to length(pList) do
        if compare(lTemp, pList[i]) = 1 then
            lTemp = pList[i]
            lPos = i
        end if
    end for

    return lPos
end function
if vUnitTesting then
    assert:assert(min_index({1}), 1, "min_index1")
    assert:assert(min_index({1,-2, 3.1,-3.2,-3.3,-4}), 6, "min_index2")
    assert:assert(min_index({"one", "two", "three", "four"}), 4, "min_index3")
end if

--: Return: The index to the element with the highest value
--: Parameters:
--:   pList = A list of one or more items to examine.
--: Description: The elements of the list are compared to each other
--:   and the index to the one with the highest value is returned.
--:
--:   This does not do a recursive compare on sub-sequences.
--:
--:   An empty sequence will cause a runtime error.
--:
--: Example:
--:    max_index({1,-2, 3.1,-3.2,-3.3,-4}) returns 3
--:    max_index({"one", "two", "three", "four"}) returns 2

---------------------------------------------------------
global function max_index(sequence pList)
---------------------------------------------------------
    object lTemp
    integer lPos

    lTemp = pList[1]
    lPos = 1
    for i = 2 to length(pList) do
        if compare(lTemp, pList[i]) = -1 then
            lTemp = pList[i]
            lPos = i
        end if
    end for

    return lPos
end function
if vUnitTesting then
    assert:assert(max_index({1}), 1, "max_index1")
    assert:assert(max_index({1,-2, 3.1,-3.2,-3.3,-4}), 3, "max_index2")
    assert:assert(max_index({"one", "two", "three", "four"}), 2, "max_index3")
end if

--: Return: The argument with the lowest value
--: Parameters:
--:   pA = Any value
--:   pB = Any value
--: Description: The lower of pA and pB is returned.
--:
--:   This does not do a recursive compare on sub-sequences.
--:
--: Example:
--:    min_AB(1,-2) returns -2
--:    min_AB("one", "two") returns "one"

---------------------------------------------------------
global function min_AB(object pA, object pB)
---------------------------------------------------------
    return min({pA, pB})
end function
if vUnitTesting then
    assert:assert(min_AB(1,-2), -2, "min_AB_1")
    assert:assert(min_AB("one", "two"), "one", "min_AB_2")
end if

--: Return: The argument with the highest value
--: Parameters:
--:   pA = Any value
--:   pB = Any value
--: Description: The higher of pA and pB is returned.
--:
--:   This does not do a recursive compare on sub-sequences.
--:
--: Example:
--:    max_AB(1,-2) returns 1
--:    max_AB("one", "two") returns "two"

---------------------------------------------------------
global function max_AB(object pA, object pB)
---------------------------------------------------------
    return max({pA, pB})
end function
if vUnitTesting then
    assert:assert(max_AB(1,-2), 1, "max_AB_1")
    assert:assert(max_AB("one", "two"), "two", "max_AB_2")
end if


I can't see the real need for smart internal do-it-all routines here as this is
some low-level routines that are all small and can be written in an uncomplicated
manner, thus easier to maintain (if needed) and probably runs faster too.

-- 
Derek Parnell
Melbourne, Australia
Skype name: derek.j.parnell

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

39. Re: Missing in misc.e

CChris wrote:

> By the way: I am not strongly against a new math.e include file, but does it
> make sense that arcsin() and friends remain in misc.e while abs(), sign() and
> friends would go to another file? I don't think it does. Just put the few math
> routines in misc.e, just like now. Or move arcsin() and friends to math.e.

IMHO arcsin() and friends shpould be moved to 'math.e'.

Regards,
   Juergen

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

40. Re: Missing in misc.e

CChris wrote:
> 
> By the way: I am not strongly against a new math.e include file, but does it
> make sense that arcsin() and friends remain in misc.e while abs(), sign() and
> friends would go to another file? I don't think it does. Just put the few math
> routines in misc.e, just like now. Or move arcsin() and friends to math.e.

Restructuring the include files would be acceptable to me; but if the majority
revolts, you can always make a new include library and call it misc_plus.e, or
somesuch. :)

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

41. Re: Missing in misc.e

I really like Derek's implementation, although I've only skimmed it and haven't
read or tested it in detail.

But maybe an empty sequence test should be made before taking pList[1]?

Also, this is pure beauty:
constant vUnitTesting = find("-unittest", command_line())


I'd never thought of doing command line switches in that way. Very clever.

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

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

42. Re: Missing in misc.e

Juergen Luethje wrote:
> 
> CChris wrote:
> 
> > By the way: I am not strongly against a new math.e include file, but does it
> > make sense that arcsin() and friends remain in misc.e while abs(), sign()
> > and
> > friends would go to another file? I don't think it does. Just put the few
> > math
> > routines in misc.e, just like now. Or move arcsin() and friends to math.e.
> 
> IMHO arcsin() and friends shpould be moved to 'math.e'.
> 
> Regards,
>    Juergen

Fine with me. We only need to state that some code may break, since
include misc.e

 will have to be replaced by }}}
<eucode>include
math.e</eucode>
{{{
 wherever these routines are used.

CChris

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

43. Re: Missing in misc.e

There is an old file out there called MATH.E

It contains :

global
constant
BLKSIZE   = 512,
MAXINT    = 32767,
BIG       = 72057594037927936.0,        -- Maximum precision of DOUBLE
HUGE      = 1.701411733192644270e38,    -- Largest DOUBLE
LOGHUGE   = 39,                         -- 10^39 --> Largest power
LN2       = 0.69314718055994530941,
LN10      = 2.30258509299404568401,
E         = 2.7182818284590452353602874,
SQRT2     = 1.41421356237309504880,
HALFSQRT2 = 0.70710678118654752440,
PI        = 3.141592653589793238462643,
QUARTPI   = 0.78539816339744830962,
HALFPI    = 1.57079632679489661923,
TWOPI     = 6.28318530717958647692,
RADPDEG   = 0.01745329251994329576
--
function sqr(atom x) return ((x) * (x)) end function
--
function sgn(atom x) if(x) < 0 then
	 return -1 else return 1 end if end function
--
procedure xswap(atom a,atom b) -- a ^= b, b ^= a, a ^= b
	 a = xor_bits(a,b) b = xor_bits(b,a) a = xor_bits(a,b) end procedure
--
procedure swap(atom a,atom b,atom c) c = a a = b b = c end procedure
--
function max(atom x,atom y) if x >= y then
	 return x else return y end if end function
--
function min(atom x,atom y) if x <= y then
	 return x else return y end if end function
--
function abs(integer x) if x < 0 then
	 return -(x) else return x end if end function -- Integer Absolute value
--
function fabs(atom x) if x < 0.0 then
	 return -(x) else return x end if end function -- Floating absolute value
--
function mod(integer x,integer y) return remainder(x,y) end function -- Integer
modulo
--
function logE(atom x) return log(x) end function       -- Natural log
--
function ln(atom x) return log(x) end function         -- Natural log



Bernie

My files in archive:
WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API 

Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan

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

44. Re: Missing in misc.e

Pete Lomax wrote:
> 
> don cole wrote:
> > > global function sign(object x)
> >         x[i]=sign(x[i])----------error------------
> > > end function
> > Hello CChris,
> > 
> >     You can't do this, can you?
> >     Call a function the middle of that function?
> C'mon Don.
> You know this.
> It is called recursion.
> In get.e, Get() calls Get().
> In file.e, walk_dir() calls walk_dir().
> In misc.e, pretty_print(), rPrint() calls rPrint().
> 
> Recursion is a very common and very powerful technique.
> 
> Pete

Hello Jason, CChris and Pete,

   O.K. O.K. I have to go back and read Wiki.


Don Cole

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

45. Re: Missing in misc.e

I started the benchmarks on the implementation I last posted:
get_min takes beyween .391 and .402s for a million calls
Passing find_max as an argument raises this to .404-.413s.
What I expected.
Using the more general find_bounds() raises the execution time to .442s. So the
canned form are probably needed, as they are 10% faster.

Using min(mu_seq,0,MM_SEQIDX) from Pete goes to .476s.

Derek's min_index() is the fastest at .231s. Expectedly, with a lot of repeated
code, that's how it is clearly faster.

CChris

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

46. Re: Missing in misc.e

I got to thinking that the problem with min() and max() may be ambiguity.
I also reflected that Eu uses remainder() rather than % or mod(). 
So I began to wonder whether this would be any better:
larger(a,b)
  smaller(a,b)
  largest(a)
  smallest(a)

Just a random thought, no more.

Regards,
Pete
PS I was actually quite pleasantly surprised to see my "all-in-one" routines
only 20% slower than CC's. Much better than I expected. Obviously the 2x hit over
DP's is another matter altogether, but I'm now tempted to resubmit...

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

47. Re: Missing in misc.e

Pete Lomax wrote:
> 
> 
> I got to thinking that the problem with min() and max() may be ambiguity.
> I also reflected that Eu uses remainder() rather than % or mod(). 
> So I began to wonder whether this would be any better:
> }}}
<eucode>
>   larger(a,b)
>   smaller(a,b)
>   largest(a)
>   smallest(a)
> </eucode>
{{{

> Just a random thought, no more.
> 
> Regards,
> Pete
> PS I was actually quite pleasantly surprised to see my "all-in-one" routines
> only 20% slower than CC's. Much better than I expected. Obviously the 2x hit
> over DP's is another matter altogether, but I'm now tempted to resubmit...

That could solve the naming problem indeed. However, I'd use "greater()" etc
instead, because the things being compared may not be numeric.

CChris

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

48. Re: Missing in misc.e

Pete Lomax wrote:
> 
> 
> I got to thinking that the problem with min() and max() may be ambiguity.
> I also reflected that Eu uses remainder() rather than % or mod(). 
> So I began to wonder whether this would be any better:
> }}}
<eucode>
>   larger(a,b)
>   smaller(a,b)
>   largest(a)
>   smallest(a)
> </eucode>
{{{

> Just a random thought, no more.

LOL   ... I had also been contemplating something similar.

  lesser(a,b)
  greater(a,b)
  least(a)
  greatest(a)


-- 
Derek Parnell
Melbourne, Australia
Skype name: derek.j.parnell

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

49. Re: Missing in misc.e

Derek Parnell wrote:

> Pete Lomax wrote:
> > 
> > 
> > I got to thinking that the problem with min() and max() may be ambiguity.
> > I also reflected that Eu uses remainder() rather than % or mod(). 
> > So I began to wonder whether this would be any better:
> > }}}
<eucode>
> >   larger(a,b)
> >   smaller(a,b)
> >   largest(a)
> >   smallest(a)
> > </eucode>
{{{

> > Just a random thought, no more.
> 
> LOL   ... I had also been contemplating something similar.
> 
>   lesser(a,b)
>   greater(a,b)
>   least(a)
>   greatest(a)

These suggestions sond nice to me, and they would solve the naming problem
in an elegant way.
Whether 'larger/st' is better or not than 'greater/st' etc. is probably
decided best by native English speakers, so I'll not vote regarding this
point.

Regards,
   Juergen

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

Search



Quick Links

User menu

Not signed in.

Misc Menu