new topic     » goto parent     » topic index » view thread      » older message » newer message

id <20030820061218.YPDI22338.tomts9-srv.bellnexxia.net@RapidEupho=
ria.com>
          for <EUforum at topica.com>; Wed, 20 Aug 2003 02:12:18 -0400
0030624 Netscape/7.1 (ax)
From: Robert Craig <rds at RapidEuphoria.com>
Subject: Re: CChris' file
ZyYy3gEHAQAAAAAABwAAAAAAZVQTag at boing.topica.com>

CChris wrote:
> Beware the long post...

I'll give a quick opinion on each item.

> The following is a commented list of features that I'd find desirable
> in Eu 2.5.
>=20
> A/ Variable management
>=20
> 1/ Pass by reference in routines
>=20
>    Description: when some code calls a routine, the routine may update so=
me vars=20
> whose references were passed to it.

I know PBR is convenient in some cases, but
currently the only way to modify a variable is
by directly assigning to it (or passing a value to a parameter).
I do not want any indirect, sneaky ways in which a variable can
be modified. Aliasing (two different names for the same thing) is bad.
Programming is simpler when you only have to think about values, not
storage locations that can be "pointed at" in various ways.

> 2/ Variable sharing
>=20
>    Description: enable two or more routines to access a symbol which is n=
ot local=20
> (filewide) or global.
>=20
>    Syntax: share x with rt1 [as y ][in file]
>    When this code is found in the declarations of routine rt2, the symbol=
 x is also made available
> to the routine rt1. x would be seen in rt1 as x if no "as" clause is ther=
e, pr as y
> otherwise. The routine rt1 may be in another file, in which case the "fil=
e" clause is needed.
>    x must have been declared before being shared.

Not necessary.
People can barely understand the scope rules as they are.

> 3/ Static variables in routines
>=20
>    Description: Allow routines to keep track of the values of private sym=
bols between executions.
>=20=20=20=20
>    Syntax: static <type> <var-list>
>    In order for a static variable to be initialized before it's first rea=
d,
> uninitialized variables should be handled.

A frill that would add some complexity
to address a trivial scope issue.
Just use file scope to retain the values.

> 4/ Allow uninitialized symbols to be passed to and returned=20
>    from routines
>=20
>    So that initialization routines can be used. Obviously, reading the va=
lue=20
> of an unitialized symbol will raise an error.

Currently, variables must be initialized before being used.
Why introduce the concept of an uninitialized variable
that can still be used. What problem are you trying to solve?
Is this another form of PBR?

> 5/ Arraying of symbols
>=20
>    Description: allow symbols to be referenced by a sequence
>=20
>    Syntax: array arrname v1[,v2,....]
>    This would create a sequence arrname whose first element aliases ident=
ifier v1,=20
> the second, if any, the symbol v2, and so on. This statement is a declara=
tion statement.
>=20
>    The idea of this, aas well as its usefulness, comes from the SAS langu=
age.

No aliases, please.

> 6/ Namespace hierarchy
>=20
>    Description: Ensures that two symbols without a namespace don't collid=
e when this was not meant.
>    When two or more global symbols are identified by the same string, Eu =
considers it an error,
> since it can't tell which one is meant. But such collisions may come from=

> conflicting names in unrelated libraries.
>    A simple solution is to adopt rules for choice, issuing a warning for =
the
> programmer's information. The rules could be:
>=20
>    a/ A conflict between explicitly namespaced symbols is an error condit=
ion;
>    b/ Let the distance between two files be the minimal numbe of include =
statements that allows=20
> the two symbols to clash. Then, only consider the symbols which were defi=
ned
> in the closest file(s).
>    c/ In case of ties, a linear link will take precedence over a broken l=
ink.
> A linear link means that the symbol is defined in a file that directly or=
 indirectly
> includes or is included by the one in which the reference is being resolv=
ed.
>    d/ In case of a tie, and if the links are of the same direction, an er=
ror must be raised.
> It means that two libraries define the same symbol, and more info is need=
ed.
>    e/ The remaining case is when a symbol is defined both in a file inclu=
ding the current file and
> in a file included in the current one. Then, the downward link (the latte=
r) is to be
> preferred.

Too complicated.
People already have trouble understanding the current
rules for namespacing.
Most programs do not even need the namespace feature.
I'm already planning to do Matt Lewis's refinement.
I don't see accidental collisions as a big issue,
or even a small issue.

> 7/ Scoped symbols
>=20
>    Descriptio: some symbols may be defined in a portion of routine/main c=
ode only.
>    Syntax: scope <var decls> ... endscope
>    Note that C-style braces, much easier to type, can't be used in Eu.

This level of scope control is too detailed.
It's not needed, and will add to people's confusion.

> B/ Routine management
>=20
> 1/ Forwarding.
>=20
>    Description: Allows to use a routine before it is defined.
>    Syntax:=20
>          forward function f([args])
>          ....
>          x=3Df(something)
>          ...
>          function f
>             ...
>             code defining the function
>             ...
>          end function
>=20
>    The alternative in 2.4 is to use call_proc/func, which obfuscates the =
code.

We crossed that bridge a long time ago.
Not interested.

> 2/ Allow discarding of function return values.
>=20
>    Description: It is sometimes useful to call a function as if it were a=
 procedure.
>    Syntax: ~thefunc([args])
>    where thefunc is a function.

Maybe. A small issue. No objection in principle.

> 3/ Return of several symbols.
>=20
>    Descritption: Allow function to simultaneously update several variable=
s.
>    Syntax: {x,y,....z}=3Df([args])
>    f must return a sequence each element of which is assigned to the corr=
esponding variable.
> Extra returned values are to be ignored.

I looked at that carefully a few years ago, and eventually grew
tired of the idea, but I wouldn't rule it out.

> 4/ Optional parameters.
>=20
>    Description: Allow the optional specification of parameters in routine=
 calls.
>    SQyntax: <routine> r([normal parms])([optional parms])
>    And, when called, the optional parameters may or may not be passed.

Like many other suggestions above, it's a refinement that adds a bit
of complexity to the language and thickens the manual,
in exchange for some minor convenience in rare cases.

> 5/ Default values for arguments.
>=20
>    Description: Allow to skip the most frequent value for a routine argum=
ent.
>    Syntax:=20
>       <routine> r(integer x=3D32767,sequence s)
>       ....
>       end <routine>
>       ...
>       y=3Dr(,s)  --argument x is 32767
>    Obviously, the comma is optional when no defaulted argulment is follow=
ed by a non-defaulted argument.

See previous comment.

> 6/ Named parameters
>=20
>    Description: Allow parameters to be passed as name=3Dvalue.
>    Named and unnamed arguments cannot be mixed in just any way.

See previous comment.

> 7/ Nested routines
>=20
>    Description: For nested routines, the code of the routine they are def=
ined in
> behaves exactly as the code outside a routine for a non-nested routine.
>    Syntax:=20
>       sequence t
>       .....
>       routine r1(...)
>       integer i
>       sequence s
>       routine r11(....)
>       integer i
>       ...
>       end routine
>       ...
>       end routine
>=20
>    In the example above, both routines r1 and r11 can see the sequence t=
=20
> as a public variable. If i is defined outside r1, r1 does not see this sy=
mbol.
> It defines another i that shadows the public i. Likewise, r11's i shadows=
 r1's i.
>    Retrieving the value of a shadowed symbol may resuire a special syntax=
.
>    Normally, a nested routine is only called by the routine in which it i=
s nested.
> This limitation might be relaxed in some cases.

I've used languages with nested routines, and they are useful sometimes,
but I think the language definition is much easier to understand when
all routines are non-nested.

> 8/ Routine_ids for builtins.
>=20
>    Description: routine_id() will return a value even for built-in routin=
es.

No reason why that hasn't been done.
I might get around to it. Not a huge demand.

> 9/ Routine redefinition.
>=20
>    Description: Coding a routine with the same name as a built-in or othe=
rwise
> previously specified routine would not cause an error, but the new routin=
e
> would be called instead of the former, hijacking its routine_id.
>=20
>    Syntax:
>       No special synntax required.
>       recover <routine decl> would undo all previous redefinitions.

"Hijacking" sounds like a recipe for confusion.

>    Note that nested routines, shared and static variables will greatly re=
duce
> the use of global syymbols, hence alleviating the namespace collisiion pr=
oblem.

I don't think there is much of a collision problem to alleviate.

> C/ Instruction flow cntrol
>=20
> 1/ Optional argument for the exit statement.
>=20
>    Description: Breaks out of several loop levels at the same time.
>    Syntax: exit [arg]
>    Arg may be:
>       a/ A positive number, which is the extra number of loop levels to l=
eave.
>       b/ A negative number, counting the loop levels from the top down. T=
hus,
> exit -1 means "exit the topmost loop".
>       c/ exit 0 can be tolerated as a synonym for plain exit.
>       d/ A label name, provided loops can be labelled.
>       e/ A for loop indexvariable name.
>=20=20=20=20=20=20=20
> 2/ Next statement
>=20
>    Description: Skips the rest of the designated loop and start a new ite=
ration.
>    Syntax: next [arg]
>    Same choices of [arg] as for exit.
>=20=20=20=20
> 3/ Retry statement
>=20
>    Description: Restarts the current iteration of the designated for loop=
.
>    Syntax: retry [arg]
>    Same rules as above.
>    retry does not quite make sense for while loops, since it would duplic=
ate next.
> So, it will count for loops only. This special behaviour might not be des=
irable=20
> if a repeat ... until construct is immplemented, because retry and next w=
ould have=20
> different meaning there..
>=20
> 4/ Exif statement
>=20
>    Description: Same as exit, but applies to if blocks.

I have no philosophical objection to these.
It's just a question of how often they are useful.
As a minimalist, I have avoided them, and probably
will continue to avoid them.

> 5/ Select statement=20=20=20
>=20
>    Description: Allows a decision to be made in more than two ways.
>    Syntax:
>       select <expr>
>          case x1: code to execute if the value of expr is x1
>          case x2: ...
>          case x3 thru x4:
>          case <5
>          case f(v,_)=3D0:
>          ....
>          [otherwise
>          ....]
>       end select
>=20=20=20=20=20=20=20
>    Each option inside the select statement is a case statement. A wide ra=
nge
> of ways to specify conditions can be devised, including using the anonymo=
us _=20
> symbol in complex constructs.
>    The optional otherwise clause is executed if no case statement caused =
the=20
> program flow to break out of the select statement.
>    Flow goes from ne case statement to the next, except when the break ke=
yword=20
> causes control to be passed to the statement following the closing end se=
lect statement.

In the early days I was considering adding a case statement,
but there was never a big user demand for it. I don't regret
leaving it out.

> 6/ xwhile loop
>=20
>    Description: same as a while loop, except that exit occurs as soon as
> the condition specified in the xwhile statement is no longer true, withou=
t the need
> for endlessly repeating tests.

Not sure I understand.

> 7/ Exception handling
>=20
>    Description: When some condition occurs, execute a specific handler.
>    Syntax: setExcHandler(condition_code,handler_routine_id)
>=20
>    The handler may access and modify any variable in scope when the handl=
er is invoked.
>    The handler may abort the program, reexecute the last instruction or r=
eturn
> normally.
>    Condition codes may not relate onlly to errors.

I'm still thinking seriously about a global exception handler.
It's easy to do, but there are some ramifications.
Fancier exception handling is probably not on.

> 8/ Guards
>=20
>    Description: Check for conditions inside a given scope and exeute code=
 when this happens.
>    Syntax:
>       on/when/whenever <condition> do
>       ...
>       end do
>    The scope of the guards may vary:
>    - on: current block only
>    - when: current routine
>    - whenever: from now on

No thanks.

> 9/ Dynamic code execution.
>=20
>    Description: Allow execution of text generated or fetched somewhere.
>    Syntax: execute(string)
>    The string in interpreted as if it had been loaded in memory in the fi=
rst
> place. Note that the include statement allows to do this, but only outsid=
e
> loops or routines.

Lots of people suggest this. Few give any examples where they would use it.=

I used a statement like this in APL years ago. I dearly wanted to find
"cool" things to do with it. Eventually I realized it was largely useless,
except for a few novelties.

The interpreter is not currently designed to allow this kind of statement.
It would be a big effort to change that, and might even slow things down
a bit for all programs.

> 10/ Selective type checking.
>=20
>    Description: Right now, either every assignment invokes type checking =
routines, or some=20
> supposedly minimal amount, not nown to programmer, is performed. The idea=
 is to
> specify variables that will be checked without type_check.
>=20
>    Syntax: check <variable decl>
>=20
>    The check prefix is ignored when type_check is on.

Seems like overkill.

> 11/ Additional type checking.
>=20
>    Description: On assignment, specified variables would go through a use=
r-definable
> set of validity checks. The user can add or remove such checks, performed=

> regardless of the type_check flag.
>=20
>    Syntax:
>      check(i1,var name/id)=20
>      add_check(i2,var name/id)
>      del_check(i2,var name/id)
>      uncheck(var nname/id)
>=20
>    These do what they say, i1 and i2 being routine_ids of additional chec=
king functions.
>    Additional type checks are coded just like ordinary type functions.

User defined type checking is not used that much as it is.
Why add a new level of complexity?

> 12/ Watch facility
>=20
>    Description: When a given variable is read, its watch function is invo=
ked,=20
> returning the value the variable (possibly) holds.
>=20
>    Syntax:
>       watch <variable decl>
>       The routine invoked will be a rtype routine, which follows the same=
 patterns=20
> and rules than type functions. Example:
>    rtype integer (integer x)
>       if x<0 then return 0
>       else return x
>       end if
>    end rtype
> would make all negative integers appear as 0.

Why?
Who needs the confusion?

> D/ Sequences and slices
>=20
> 1/ Negatives indexes
>=20
>    Description: inside any sequence index specifiation, a negative value =
might=20
> be used to count the elements backwards. So, longsequencename[length(long=
sequencename)]
> could be coded longsequencename[-1].

Accidental uses of negative indexes likely won't be caught as errors.
Why is this important?

> 2/ More slices
>=20
>    Decription: slices might appear in index specifications in other place=
s than just the last.
>    Thus, matrix[..][3] would be the 3rd row of a column-bnased matrix.

I implemented that in "Fourier", the language I did before Euphoria.
It was useful there because the parallel machine could do the operation
in hardware. In the Euphoria interpreter, I have no ultra-fast way to
implement this, so you might as well do it yourself in the
few places where it comes up. Maybe make a routine for it.

> 3/ Shorthands for "length(this)"
>=20
>    Description: Allow more flexible coding of slices that extend to the e=
nd
> of a sequence.
>    Syntax: matrix[..][3]      --see above
>            stack[$]           --last element of stack
>            word[2..]          --chop first letter off word

I agree that it's often cumbersome to write stuff like:
    longvariablename[1..length(longvariablename)-1]

I just don't know the best way to improve that.
Obviously:
    longvariablename[1..$-1]
is one way. I don't really like having lots of special
characters in the language though. They scare away beginners.

> 4/ Composition of sequences
>=20
>    Description: defines a subsequence using a sequence of indexes.
>    Syntax: t=3D{3,-1,5,3}
>            s=3D<some sequence>
>            s1=3Ds=F8t    s1 is a sequence of lenth 4: {s[3],s[-1],s[5],s[=
3]}
>    Pairs in t could specify slices.

Probably wouldn't be used often enough.
Easy enough to do with a loop.

> 5/ Dynamic indexing
>=20
>    Description: Allow variable length index specification
>    Syntax: s=3D{1,3,2}
>            t=3Du[[s]]     --t=3Du[1][3][2]
>=20
>    Again, pairs could be used in s to specify slices.

Wouldn't be used often enough.
There are many possibilities for defining subscripting a sequence
with a sequence. Maybe some day.

> 6/ Sequence manipulation routines
>=20
>    Description: replace, insert and move elemnts around in a sequence.
>    Syntax:
>       replace(seq,places_list,subst_list)=20
>          --places_list is a list of pairs of indexes delimiting subsequen=
ces in seq.
>          --Each of these will be replaced by the matching element in subs=
t_list.
>       insert(seq,where,x)   --x is inserted at position where in seq, who=
se length increased by 1
>       inserts(seq,where,x)  --if x is a sequence, its elements are insert=
ed starting at position=20
>          --where in seq.If x is an atom, same as insert.
>       move(seq,start,end,where)
>          --the subsequence seq[start..end] is moved so that it starts at =
where.
>       remove'szq,where)
>          --where is an index or a pair of indexes specifying element(s) t=
o be removed from seq.
>=20=20=20=20=20=20=20=20=20=20
>       Note that all these could be just some functions in misc.e Their be=
ing
> built-ins would probably increase speed.

I don't mind adding some more general-purpose functions to misc.e.

>  E/ Object programming capabilities.

Object oriented programming is great in theory,
but once you head down that road you will probably
end up doubling the size of the manual, trying to
explain the nuances and interactions among all the
different features. We can do a form of object oriented
programming using libraries like Mike Nelson's.

> F/ Miscellaneous
>=20
> 1/ Pre- and post-inc/decremnet operators C-style
> 2/ Allow concatenation of logical relations, such as 0<=3Dx<=3D9.
> 3/ Allow assignments inside conditions. The symbol :=3D could be used her=
e
> since =3D has a relational meaning.

Unnecessary frills.

-----------------

Thanks for your suggestions.
I'll save them in my Suggestions folder and I might
act on some of them.

Everyone has a different taste in programming languages.
My vision for Euphoria, since day 1, has been to create
a powerful, easy-to-learn, minimal, reliable and fast language.
I don't measure the progress of Euphoria by the number of
core language statements added each year.
New growth should mainly be in libraries, tools
and porting. BTW, someone with the source has recently ported Euphoria
to the Franklin eBookMan PDA - various text-mode programs are running.

Briefly, some other issues:

open source - I have no plans to make Euphoria open source or free in the
forseeable future. If I get tired of working on it, I'll consider it.
Keep in mind 95% of the Interpreter source is available to anyone for $49.
and keep in mind 95% of the functionality is already free to anyone.
Most libraries are open source.
I've gone as far as I can in the free and open direction without
giving up my income.

Euphoria sales - July 2003 set a new all-time record for registrations,
upgrades, and dollars income. Thanks to all who registered or upgraded.
Of course I'm not getting rich. I'm still driving a badly rusting
1989 Corolla. smile

Regards,
    Rob Craig
    Rapid Deployment Software
    http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu