1. New keywords: ifdef, elsifdef, end ifdef
Ok, in SVN revision 452, there are 2 new keywords. ifdef and elsifdef. The ifdef
is combined with an existing keyword, end, to make a complete set of conditional
compilation keywords.
A quick rundown:
1. Setting defines can be done in 2 ways:
1a..... with define=debug
....... this can be given multiple times to define more than one item
1b..... exu/ecu, ex/exw/exwc/ecw -D debug
....... -D parameter can be given multiple times to define more than one item
2. Clearing defines can be done with without:
1a..... without define=debug
....... this turns off the debug define.
3. Predefined "defines"
2a..... Current operating system (WIN32, DOS32, LINUX, FREEBSD)
2b..... Current Euphoria version (EU400)
4. ifdef/elsifdef/end ifdef work on static defines. You cannot execute dynamic
code in your ifdef/elseifdef.
A few examples:
ifdef debug then
puts(1, "DEBUG\n")
end ifdef
exwc myprog.e --- no output
exwc -D debug myprog.e ---- "DEBUG"
with define=debug
ifdef debug then
puts(1, "DEBUG\n")
end ifdef
exwc myprog.e --- "DEBUG"
Conditional includes
ifdef debug then
include safe.e
else
include machine.e
end ifdef
platform() replacement
sequence name
ifdef WIN32 then
name = "Windows"
global procedure say_hello()
puts(1, "Hello from Windows!\n")
end procedure
elsifdef LINUX then
name = "Linux"
global procedure say_hello()
puts(1, "Hello from Linux!\n")
end procedure
elsifdef DOS32 then
name = "DOS"
global procedure say_hello()
puts(1, "Hello from DOS!\n")
end procedure
end ifdef
say_hello()
puts(1, "You are on " & name & "\n")
with/without
with define=debug
if debug then
puts(1, "Hello Debug\n")
end ifdef
without define=debug
if debug then
puts(1, "Serious error, you should not be here!\n")
end ifdef
Things you *cannot* do:
sequence name
name = prompt_string("Enter style:")
ifdef name = "SIMPLE" then
end ifdef
ifdef myfunc() then
end ifdef
ifdef age = 32 then
end ifdef
All three of the above are dynamic. i.e. it depends on code to be executing,
thus those are decisions that can take place only in the interpreter, not at
parse time. If you need the above, then you use the normal if/elsif/else/end if
statements.
This is in SVN right now for anyone who wishes to test it, play with it. There
is a unit test added for it: tests/t_condcmp.e ... 672 tests now and counting!
--
Jeremy Cowgar
http://jeremy.cowgar.com
2. Re: New keywords: ifdef, elsifdef, end ifdef
I wanted to follow up after reading my own post
First, the else keyword also works inside of an ifdef, elsifdef, else, end ifdef
structure.
Second, this is not just a nice addition to use, it will speed your code up in
any case where it is useful. How does it do it? Take this for example:
for i = 1 to 10000 do
if debug = 1 then
printf(1, "Loop iteration %i\n", {i})
end if
--- code
end for
Each iteration, the interpreter must check to see if debug is equal to 1. Now,
look at this example:
for i = 1 to 10000 do
ifdef debug then
printf(1, "Loop iteration %i\n", {i})
end ifdef
--- code
end for
The interpreter *never* checks if debug is on or off. How does it do it? During
the parsing of your source code, the ifdef keyword is found and instead of
"emitting" the code to the interpreter (IL code), the parser looks in a sequence
of defines to see if the define you requested exists. If so, then it ignores
itself (i.e. the ifdef debug then) and allows the parser to continue to "emit"
the code in it's own block to the interpreter (IL code). If it is not defined,
then the parser skips all code, not emiting IL code for the entire contained
block. Thus, the interpreter never even knows the code exists.
So, in the above example, if debug is not defined, then the interpreter thinks
the application looks like:
for i = 1 to 10000 do
--- code
end for
If debug is defined, then the interpreter thinks the application looks like:
for i = 1 to 10000 do
printf(1, "Loop iteration %i\n", {i})
--- code
end for
Again, I want to stress for those who did not read a few previous posts under a
different subject. This is *not* a pre-processor. A pre-process will slow things
down. This does not. A pre-processor will scan the source contents before the
parser ever get's it and filter out any unwanted code. Once the pre-processor is
done, it then sends it's processed code to the parser for the real scanning. The
new ifdef construct happens during the normal parse. It's use will only speed
things up, not slow them down. If you do not use the ifdef keyword then it will
have zero effect on your code.
--
Jeremy Cowgar
http://jeremy.cowgar.com
3. Re: New keywords: ifdef, elsifdef, end ifdef
Jeremy Cowgar wrote:
>
> platform() replacement
This being the Internet and all, I'm going to pick on your arbitrary
example for the sake of argumentativeness:
sequence name
ifdef WIN32 then
name = "Windows"
elsifdef LINUX then
name = "Linux"
elsifdef DOS32 then
name = "DOS"
end ifdef
global procedure say_hello()
printf(1, "Hello from %s\n", {name})
end procedure
say_hello()
puts(1, "You are on " & name & "\n")
Seriously, though. This is good stuff.
Matt
4. Re: New keywords: ifdef, elsifdef, end ifdef
Matt Lewis wrote:
>
> This being the Internet and all, I'm going to pick on your arbitrary
> example for the sake of argumentativeness:
>
I wanted to merely show you could make different functions under an ifdef
statement, that's all. My examples aren't always proper coding, such as the loop
var names being a, b, c
--
Jeremy Cowgar
http://jeremy.cowgar.com
5. Re: New keywords: ifdef, elsifdef, end ifdef
Jeremy Cowgar wrote:
>
> Matt Lewis wrote:
> >
> > This being the Internet and all, I'm going to pick on your arbitrary
> > example for the sake of argumentativeness:
> >
>
> I wanted to merely show you could make different functions under an ifdef
> statement, that's all. My
> examples aren't always proper coding, such as the loop var names being a, b, c
>
>
> --
> Jeremy Cowgar
> <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a>
Heh, I was just picking on your choice of examples, using meaningful names as
labels vice single letter loop variables, thereby making the label examples look
a lot better.
--
A complex system that works is invariably found to have evolved from a simple
system that works.
--John Gall's 15th law of Systemantics.
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.
6. Re: New keywords: ifdef, elsifdef, end ifdef
- Posted by D. Newhall <derek_newhall at yaho?.?om>
May 13, 2008
-
Last edited May 14, 2008
Jeremy Cowgar wrote:
>
> Ok, in SVN revision 452, there are 2 new keywords. ifdef and elsifdef. The
> ifdef
> is combined with an existing keyword, end, to make a complete set of
> conditional
> compilation keywords.
>
> A quick rundown:
>
> 1. Setting defines can be done in 2 ways:
> 1a..... with define=debug
> ....... this can be given multiple times to define more than one item
> 1b..... exu/ecu, ex/exw/exwc/ecw -D debug
> ....... -D parameter can be given multiple times to define more than one item
>
> 2. Clearing defines can be done with without:
> 1a..... without define=debug
> ....... this turns off the debug define.
>
> 3. Predefined "defines"
> 2a..... Current operating system (WIN32, DOS32, LINUX, FREEBSD)
> 2b..... Current Euphoria version (EU400)
>
> 4. ifdef/elsifdef/end ifdef work on static defines. You cannot execute dynamic
> code in your ifdef/elseifdef.
>
(snip examples)
>
> All three of the above are dynamic. i.e. it depends on code to be executing,
> thus those are decisions that can take place only in the interpreter, not at
> parse time. If you need the above, then you use the normal if/elsif/else/end
> if statements.
>
> This is in SVN right now for anyone who wishes to test it, play with it. There
> is a unit test added for it: tests/t_condcmp.e ... 672 tests now and counting!
>
> --
> Jeremy Cowgar
> <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a>
Now, granted I've just dropped in after not even looking at Euphoria for a year
or so, but the above looks really ugly to me. To me, it looks like some
bastardized version of C macros.
I considered Euphoria to be one of cleanest "scripting languages" around.
Granted, it has its occasional rough edges which you quickly got used to
(remember when '$' first appeared?) but overall the design of the language and
the library is really, really clean. The 'ifdef' and 'elsifdef' statements seem
much less clean than the rest of the language. Also, what about such constructs
like a 'ifnotdef' or an 'elsedef'? These would also be needed as well and they
are even uglier.
This is just me, however, and there are worse designs than what's been proposed.
Moreover, what I would want in a language is probably not what you would want in
one. I think compile-time coding is a terribly important thing (it is actually
one of the things that might make me come back to Euphoria) but I would want just
that, compile-time coding, not just simple conditional including.
(Odd Lisp-influenced tangent follows)
In case you don't see what I mean I'll give you an example. (The syntax used was
the one from a preprocessor I wrote for my own use a while ago. It just called
the Euphoria interpreter after parsing. Everything after a '#' is done at compile
time. I'm not saying this syntax is better necessarily (although, I do partially
prefer it), I'm just illustrating what would I think would be the "right thing"
to do in this case.) This code (which is based on code I actually used in a
project) opens a file and puts all the variable/value pairs from each line inside
the code itself.
-- Program code
#sequence filenm, line, var_val
#integer fn
#filenm = "consts.conf"
#fn = open(filenm, "r")
#line = gets(fn)
#while sequence(line) do
# var_val = split(line, '\t')
-- This "puts the statement in the code"
-- (it just puts a string into a buffer)
# statement("sequence " & var_val[1])
# statement(var_val[1] & " = " & var_val[2])
# end while
-- Program code
This code was used to allow a user to embed constants and variables in the
program so they could use them later on in the code because later on there was
some code that allowed the user to specify any include files they wrote to etend
the program. I use the Common Lisp equivalent of these constructs every time I
code.
An alternative syntax could be to stick the compile-time code into a block of
some sort, such as:
-- Assuming we defined the above code in a procedure...
compile_time -- This could instead be 'macro' or anything really
read_consts()
end compile_time
There is of course the argument that supporting this would make the interpreter
more complex and perhaps slower is a very valid argument that needs to be
considered. There is not, I feel, an argument that such constructs would not be
used. It obviously would be used for everything 'ifdef' is intended for plus it
could be used for more advanced stuff which some people need (I wrote a
preprocessor program so I could this type of programming). Heck, you might even
get some Lispers migrate to Euphoria.
I don't expect this to ever be supported, I'm just illustrating what I think the
"ideal" thing to support would be. Regardless, I still feel that the 'ifdef'and
'elseifdef' constructs need to be revised for the sake of the language's clarity.
I still have a deep (if not currently utilized) love for the language and
recommend Euphoria to beginning programmers so I'd hate to have something which
seems so counter-intuitive to the language's goals included in it.
- Derek
7. Re: New keywords: ifdef, elsifdef, end ifdef
- Posted by Mike777 <anon4321 at gmail.c??>
May 13, 2008
-
Last edited May 14, 2008
D. Newhall wrote:
>
> Jeremy Cowgar wrote:
> >
> > Ok, in SVN revision 452, there are 2 new keywords. ifdef and elsifdef. The
> > ifdef
> > is combined with an existing keyword, end, to make a complete set of
> > conditional
> > compilation keywords.
> >
> > A quick rundown:
> >
> > 1. Setting defines can be done in 2 ways:
> > 1a..... with define=debug
> > ....... this can be given multiple times to define more than one item
> > 1b..... exu/ecu, ex/exw/exwc/ecw -D debug
> > ....... -D parameter can be given multiple times to define more than one
> > item
> >
> > 2. Clearing defines can be done with without:
> > 1a..... without define=debug
> > ....... this turns off the debug define.
> >
> > 3. Predefined "defines"
> > 2a..... Current operating system (WIN32, DOS32, LINUX, FREEBSD)
> > 2b..... Current Euphoria version (EU400)
> >
> > 4. ifdef/elsifdef/end ifdef work on static defines. You cannot execute
> > dynamic
> > code in your ifdef/elseifdef.
> >
> (snip examples)
> >
> > All three of the above are dynamic. i.e. it depends on code to be executing,
> > thus those are decisions that can take place only in the interpreter, not at
> > parse time. If you need the above, then you use the normal if/elsif/else/end
> > if statements.
> >
> > This is in SVN right now for anyone who wishes to test it, play with it.
> > There
> > is a unit test added for it: tests/t_condcmp.e ... 672 tests now and
> > counting!
> >
> > --
> > Jeremy Cowgar
> > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a>
>
> Now, granted I've just dropped in after not even looking at Euphoria for a
> year
> or so, but the above looks really ugly to me. To me, it looks like some
> bastardized
> version of C macros.
>
> I considered Euphoria to be one of cleanest "scripting languages" around.
> Granted,
> it has its occasional rough edges which you quickly got used to (remember when
> '$' first appeared?) but overall the design of the language and the library
> is really, really clean. The 'ifdef' and 'elsifdef' statements seem much less
> clean than the rest of the language. Also, what about such constructs like a
> 'ifnotdef' or an 'elsedef'? These would also be needed as well and they are
> even uglier.
>
> This is just me, however, and there are worse designs than what's been
> proposed.
> Moreover, what I would want in a language is probably not what you would want
> in one. I think compile-time coding is a terribly important thing (it is
> actually
> one of the things that might make me come back to Euphoria) but I would want
> just that, compile-time coding, not just simple conditional including.
>
>
> (Odd Lisp-influenced tangent follows)
>
> In case you don't see what I mean I'll give you an example. (The syntax used
> was the one from a preprocessor I wrote for my own use a while ago. It just
> called the Euphoria interpreter after parsing. Everything after a '#' is done
> at compile time. I'm not saying this syntax is better necessarily (although,
> I do partially prefer it), I'm just illustrating what would I think would be
> the "right thing" to do in this case.) This code (which is based on code I
> actually
> used in a project) opens a file and puts all the variable/value pairs from
> each
> line inside the code itself.
>
> }}}
<eucode>
> -- Program code
> #sequence filenm, line, var_val
> #integer fn
> #filenm = "consts.conf"
> #fn = open(filenm, "r")
> #line = gets(fn)
> #while sequence(line) do
> # var_val = split(line, '\t')
> -- This "puts the statement in the code"
> -- (it just puts a string into a buffer)
> # statement("sequence " & var_val[1])
> # statement(var_val[1] & " = " & var_val[2])
> # end while
> -- Program code
> </eucode>
{{{
>
> This code was used to allow a user to embed constants and variables in the
> program
> so they could use them later on in the code because later on there was some
> code that allowed the user to specify any include files they wrote to etend
> the program. I use the Common Lisp equivalent of these constructs every time
> I code.
>
> An alternative syntax could be to stick the compile-time code into a block of
> some sort, such as:
>
> -- Assuming we defined the above code in a procedure...
> compile_time -- This could instead be 'macro' or anything really
> read_consts()
> end compile_time
>
> There is of course the argument that supporting this would make the
> interpreter
> more complex and perhaps slower is a very valid argument that needs to be
> considered.
> There is not, I feel, an argument that such constructs would not be used. It
> obviously would be used for everything 'ifdef' is intended for plus it could
> be used for more advanced stuff which some people need (I wrote a preprocessor
> program so I could this type of programming). Heck, you might even get some
> Lispers migrate to Euphoria.
>
>
> I don't expect this to ever be supported, I'm just illustrating what I think
> the "ideal" thing to support would be. Regardless, I still feel that the
> 'ifdef'and
> 'elseifdef' constructs need to be revised for the sake of the language's
> clarity.
> I still have a deep (if not currently utilized) love for the language and
> recommend
> Euphoria to beginning programmers so I'd hate to have something which seems
> so counter-intuitive to the language's goals included in it.
Derek,
Unless I am not understanding, your construct seems to miss the entire point of
the exercise. In the version proposed by Jeremy, you end up modifying the code
which is sent to the compiler. If the code isn't there, it doesn't run. If it
doesn't run, it doesn't slow down the execution. Further, it provides for
various levels of conditional compiles effortlessly.
For example, someone might have a Trial version and a regular version of their
program. With Jeremy's construct, the Trial version is compiled without the
regular version's code (in places where the code is different, of course),
thereby absolutely ensuring that no reverse engineering of any sort can discover
things intended to be undiscovered by the programmer.
With your construct, all you have done is allowed the program to run its various
tests with the knowledge the they will succeed or fail based on reference to an
outside configuration file. But the tests themselves must interrogate the
resulting variables in order to decide what to do.
I admit that it has been over 30 years since I dabbled in LISP (and the current
incarnation probably has little resemblance to what I struggled with at
university), but I think you are looking at this a bit differently than the way
it is intended to be viewed.
Mike
8. Re: New keywords: ifdef, elsifdef, end ifdef
- Posted by Jeremy Cowgar <jeremy at cow?ar.c?m>
May 13, 2008
-
Last edited May 14, 2008
D. Newhall wrote:
>
> Now, granted I've just dropped in after not even looking at Euphoria for a
> year
> or so, but the above looks really ugly to me. To me, it looks like some
> bastardized
> version of C macros.
Yes, but I'm not sure I see that as a problem?
> I considered Euphoria to be one of cleanest "scripting languages" around.
> Granted,
> it has its occasional rough edges which you quickly got used to (remember when
> '$' first appeared?) but overall the design of the language and the library
> is really, really clean. The 'ifdef' and 'elsifdef' statements seem much less
> clean than the rest of the language. Also, what about such constructs like a
> 'ifnotdef' or an 'elsedef'? These would also be needed as well and they are
> even uglier.
Hm, what's wrong with
ifdef !debug then
-- code
end ifdef
Oh, also there is the else statement that works as every Euphoria programmer
already knows (because the whole ifdef is modeled after if statements afterall):
ifdef debug then
puts(1, "Debug version\n")
else
puts(1, "Release version\n")
end ifdef
No need for a elseifdef. We would want to introduce less keywords to make it
easier for the programmer and faster in the parsing.
> This is just me, however, and there are worse designs than what's been
> proposed.
> Moreover, what I would want in a language is probably not what you would want
> in one. I think compile-time coding is a terribly important thing (it is
> actually
> one of the things that might make me come back to Euphoria) but I would want
> just that, compile-time coding, not just simple conditional including.
What has been provided with the ifdef/elsifdef *is* conditional compilation. It
really has nothing to do with conditional including. Conditional includes is just
a side effect that was planned to occur with the design.
> (Odd Lisp-influenced tangent follows)
>
> In case you don't see what I mean I'll give you an example. (The syntax used
> was the one from a preprocessor I wrote for my own use a while ago. It just
> called the Euphoria interpreter after parsing. Everything after a '#' is done
> at compile time. I'm not saying this syntax is better necessarily (although,
> I do partially prefer it), I'm just illustrating what would I think would be
> the "right thing" to do in this case.) This code (which is based on code I
> actually
> used in a project) opens a file and puts all the variable/value pairs from
> each
> line inside the code itself.
Hm. If it is not better necessarily, can you please give me an example of what
is better so I may be able to change ifdef/elsifdef to be better as well?
> }}}
<eucode>
> -- Program code
> #sequence filenm, line, var_val
> #integer fn
> #filenm = "consts.conf"
> #fn = open(filenm, "r")
> #line = gets(fn)
> #while sequence(line) do
> # var_val = split(line, '\t')
> -- This "puts the statement in the code"
> -- (it just puts a string into a buffer)
> # statement("sequence " & var_val[1])
> # statement(var_val[1] & " = " & var_val[2])
> # end while
> -- Program code
> </eucode>
{{{
>
> This code was used to allow a user to embed constants and variables in the
> program
> so they could use them later on in the code because later on there was some
> code that allowed the user to specify any include files they wrote to etend
> the program. I use the Common Lisp equivalent of these constructs every time
> I code.
I am sorry, but I do not follow the syntax or what the above example is doing.
Can you give me an example of what the input is and then what the output is? i.e.
what is sent to the pre-processor then what is passed on to the
interpreter/translator?
> An alternative syntax could be to stick the compile-time code into a block of
> some sort, such as:
>
> -- Assuming we defined the above code in a procedure...
> compile_time -- This could instead be 'macro' or anything really
> read_consts()
> end compile_time
Yes, in the ifdef/elsifdef scheme, there is no execution involved of any code,
however, I treat that as a feature which keeps Euphoria simple, also keeps it
lightning fast.
> There is of course the argument that supporting this would make the
> interpreter
> more complex and perhaps slower is a very valid argument that needs to be
> considered.
I wouldn't worry about the complexity too much, as long as it is maintainable
code, but the performance is certainly a major concern. One of the things that
makes Euphoria so attractive to many is it is just about the fastest scripting
language out there and on top of that, it compiles to a real binary! How cool!
Now, when you introduce a pre-processor into the stage, that's when things can
begin to slow down. As with C, it's not a big deal because the pre-processor
takes place only during the compilation. Then when the user uses the application,
it's compiled. It really does not matter how much the C pre-processor slows the
compilation down because for the most part, you do not care how long it takes C
to compile (within reason, i.e. I know applications that take 6-8 hours to
compile, introducing even a slight delay in the compiler at those times, makes a
huge difference, but most of us (myself included) never have to deal with such a
huge app).
When it comes to Euphoria the use of the pre-processor has a huge impact. Each
time the user runs the script, it is effected. If you have a large Euphoria
application the delay of execution would be very noticeable. The pre-processor
has to load all the code, scan it for it's own tokens, do string replacements (in
your case execute some code as well to come up with results), then reconstruct
the source and presumably write back to disk a new processed application in which
the Euphoria interpreter is then called on.
Now where it gets worse is that the pre-processor has to run on everyones code
all the time. It has no idea if the user used any preprocessor tokens that it
should process until it looks. The argument could be made that the user could
pass a command line parameter, such as -pp, but then you have the whole
compatibility of libraries the user may depend on. Does it need the
pre-processor? Thus, it is always a performance hit.
The ifdef/elsifdef keywords scheme has no such problem. It is only invoked when
the normal parser comes across an ifdef statement. The parser then does 1 if
statment check internally to determine if the nested block should be emitted to
IL (or C) or not. All conditions are short circuited. So, if the first condition
in a multiple condition ifdef/elsifdef statement is true, then the code is emited
as normal, w/no injection of speed processing what-so-ever. It simply returns
control to the parser and it continues it's parsing as normal. This is the same
way any statement works in Euphoria. Now, where the real speed increase comes in
is when a statement is false. When a statement is false, then the ifdef/elsifdef
command eats all tokens until it finds the next condition to check. If that
condition is false as well (or if it found a true condition already), then
ifdef/elsifdef contiunes to eat tokens until it finally finds an end ifdef. This
"eating" takes place as ultra-speed.
> There is not, I feel, an argument that such constructs would not be used. It
> obviously would be used for everything 'ifdef' is intended for plus it could
> be used for more advanced stuff which some people need (I wrote a preprocessor
> program so I could this type of programming). Heck, you might even get some
> Lispers migrate to Euphoria.
>
>
> I don't expect this to ever be supported, I'm just illustrating what I think
> the "ideal" thing to support would be. Regardless, I still feel that the
> 'ifdef'and
> 'elseifdef' constructs need to be revised for the sake of the language's
> clarity.
Can you please give a bit clearer of an example or explain better what the above
example does?
> I still have a deep (if not currently utilized) love for the language and
> recommend
> Euphoria to beginning programmers so I'd hate to have something which seems
> so counter-intuitive to the language's goals included in it.
>
What do you think is counter-intuitive and how is ifdef/elsifdef against the
language goals? I am not arguing, I am trying to learn.
Now about being able to introduce conditional compile time constants,
ifdef/elsifdef can do that fine. It can also introduce compile time variables. It
cannot dynamically execute code and insert the result of that said code during
parsing time (if that's what your above example did, I'm still a bit unclear
about it).
sequence version
ifdef shareware_edition then
constant SHAREWARE = 1
version = "1.0 Shareware"
else
constant SHAREWARE = 0
version = "1.0 Registered"
end ifdef
Now, the above code is not a good example of how to protect your application,
I'm just using it as an example. Now, you can certainly change how a variable is
initialized dynamically once the code begins to execute:
sequence version
ifdef shareware_edition then
version = shareware_version()
else
version = registered_version()
end ifdef
Thank you for your input, I am looking forward to more about how to make things
better yet.
--
Jeremy Cowgar
http://jeremy.cowgar.com
9. Re: New keywords: ifdef, elsifdef, end ifdef
Jeremy Cowgar wrote:
> }}}
<eucode>
> ifdef debug then
> puts(1, "Debug version\n")
> else
> puts(1, "Release version\n")
> end ifdef
> </eucode>
{{{
>
> No need for a elseifdef. We would want to introduce less keywords to make it
> easier for the programmer and faster in the parsing.
Congratulations on implementing this feature!
This is a feature that I wished very much.
However, I don't really like the syntax.
Especially the elsifdef, it looks like a cramped abbreviation.
Other suggestions that came in mind:
1. Use another keyword after "if" like "defined"
if defined LINUX then
-- linux code
elsif defined WIN32 then
-- win32 code
else
-- whatever
end if
Adv: only 1 new keyword instead of 2. Less abbreviation.
Dis: harder to implement (?)
2. Use static if (idea from D)
static if VERSION > 400 then
puts(1, "you are in the future!")
elsif VERSION < 400 then
puts(1, "Please upgrade")
else
puts(1, "hohoho");
end if
Adv: One keyword instead of 2. Only need to write "static" once instead of 2
times "defined" like above. Can use >, <, = instead of just boolean testing.
Dis: same as above
3. Use $ for "preprocessor" variables (variables that are defined during
compilation), no need to use new keywords.
if $VERSION > 400 then
puts(1, "you are in the future!")
elsif $DOS32 then
puts(1, "good old-timer")
else
puts(1, "hohoho");
end if
Adv: The $ sign makes it stands out from normal if-statement. $ sign is already
used so no new keyword or symbol introduced. Can use >, <, = instead of just
boolean testing.
Dis: none?
____
Personally I prefer the 3rd point above.
How do you think?
10. Re: New keywords: ifdef, elsifdef, end ifdef
yuku wrote:
>
> However, I don't really like the syntax.
> Especially the elsifdef, it looks like a cramped abbreviation.
>
I was not too happy. I think my first post about the feature was asking for
suggestions. It's functional and I think it can grow on you, but at first sight,
ifdef, elsifdef is, eh?
> Other suggestions that came in mind:
>
> 1. Use another keyword after "if" like "defined"
>
> }}}
<eucode>
> if defined LINUX then
> -- linux code
> elsif defined WIN32 then
> -- win32 code
> else
> -- whatever
> end if
> </eucode>
{{{
>
> Adv: only 1 new keyword instead of 2. Less abbreviation.
> Dis: harder to implement (?)
>
It's not only harder to implement but it would slow *all* programs down. The
reason for this is each and every *if* statement that the parser would come
across would have to be checked for an optional "defined" keyword. IMHO, this
shoots down the above syntax.
> 2. Use static if (idea from D)
>
> }}}
<eucode>
> static if VERSION > 400 then
> puts(1, "you are in the future!")
> elsif VERSION < 400 then
> puts(1, "Please upgrade")
> else
> puts(1, "hohoho");
> end if
> </eucode>
{{{
>
> Adv: One keyword instead of 2. Only need to write "static" once instead of 2
> times
> "defined" like above. Can use >, <, = instead of just boolean testing.
> Dis: same as above
>
This has potential. The static keyword would be the keyword and send the parser
into a new Static_statement() function that would then begin looking for the if,
elsif, end if statements. This would cause zero slow down in existing
applications and in applications that utilize it, it would only cause speed
increases.
However, I dis-like using the word static as static usually means something
totally different. For instance:
function next()
static integer id
if !defined(id) then
id = 0
end if
id += 1
return id
end function
There are other uses for the static keyword as well. Perhaps a different
"trigger" word could be found? This is a good idea, static is just not the best
choice, I do not think.
> 3. Use $ for "preprocessor" variables (variables that are defined during
> compilation),
> no need to use new keywords.
>
> }}}
<eucode>
> if $VERSION > 400 then
> puts(1, "you are in the future!")
> elsif $DOS32 then
> puts(1, "good old-timer")
> else
> puts(1, "hohoho");
> end if
> </eucode>
{{{
>
> Adv: The $ sign makes it stands out from normal if-statement. $ sign is
> already
> used so no new keyword or symbol introduced. Can use >, <, = instead of just
> boolean testing.
> Dis: none?
>
Has the same problem as the first option. I think your second idea is the best
one but with a different trigger word. One thing that may be confusing about
that, and possibly a reason not to use a trigger word would be people would think
you could then do:
compile-time procedure init()
-- compute big long value that has all sorts of
-- nested loops, complex decisions, random number
-- generation and takes 10 minutes to come up with
-- the final answer.
answer = result_of_everything_above
end procedure
and by the nature of "compile-time" keyword, that sounds perfectly legit but not
currently (or ever that I can see in my finite mind) possible.
So, we should carefully consider the use of a trigger word. It makes the if
statement look better, but provides other real benefit and could cause confusion.
Sure, people could read the manual, but how often do they and should they have
to? I know for the most part I can look at a few examples of code in a new
language and begin programming in that language. Sure, there are minor nuances
that must be learned by reading document references, but is this one of those
things or no?
I like the looks of it quite a bit better, but ...
Thoughts?
--
Jeremy Cowgar
http://jeremy.cowgar.com
11. Re: New keywords: ifdef, elsifdef, end ifdef
Jeremy Cowgar wrote:
> yuku wrote:
> > 2. Use static if (idea from D)
> >
> > }}}
<eucode>
> > static if VERSION > 400 then
> > puts(1, "you are in the future!")
> > elsif VERSION < 400 then
> > puts(1, "Please upgrade")
> > else
> > puts(1, "hohoho");
> > end if
> > </eucode>
{{{
> >
> > Adv: One keyword instead of 2. Only need to write "static" once instead of 2
> > times
> > "defined" like above. Can use >, <, = instead of just boolean testing.
> > Dis: same as above
I love the D language but this use of 'static' is one of the most blatant warts
in its syntax. There seems to be an absolute terror by the D developers to use
new keywords so they use existing ones in new and confusing ways.
I have no problem with the proposed keyword 'ifdef' to signal the start of
parser-time condition testing. The 'else' and 'elsif' keywords can be comfortably
reused in this context as they semantically mean the same whether processed at
parser-time or at execute-time, the only difference is *when* it gets processed.
--
Derek Parnell
Melbourne, Australia
Skype name: derek.j.parnell
12. Re: New keywords: ifdef, elsifdef, end ifdef
Derek Parnell wrote:
>
> I have no problem with the proposed keyword 'ifdef' to signal the start of
> parser-time
> condition testing. The 'else' and 'elsif' keywords can be comfortably reused
> in this context as they semantically mean the same whether processed at
> parser-time
> or at execute-time, the only difference is *when* it gets processed.
>
I was thinking of doing that but I did not want to cause confusion. i.e. if ...
then ... elsif ... else ... end if vs. ifdef ... then ... elsifdef ... end
ifdef
I like elsif better and it would reduce one keyword count, but I'm not sure
about it's clarity? Also, it would then blend in better with other standard
if/elsif/end if statements? Thinking aloud seeking input.
Now that the functionality exists, it's easy to change its syntax. This is what
Open Source software is about, isn't this great? Ideas implemented, improved and
furthered.
--
Jeremy Cowgar
http://jeremy.cowgar.com
13. Re: New keywords: ifdef, elsifdef, end ifdef
Jeremy Cowgar wrote:
>
> Derek Parnell wrote:
> >
> > I have no problem with the proposed keyword 'ifdef' to signal the start of
> > parser-time
> > condition testing. The 'else' and 'elsif' keywords can be comfortably reused
> > in this context as they semantically mean the same whether processed at
> > parser-time
> > or at execute-time, the only difference is *when* it gets processed.
> >
>
> I was thinking of doing that but I did not want to cause confusion. i.e. if
> ... then ... elsif ... else ... end if vs. ifdef ... then ... elsifdef ...
> end ifdef
>
> I like elsif better and it would reduce one keyword count, but I'm not sure
> about it's clarity? Also, it would then blend in better with other standard
> if/elsif/end if statements? Thinking aloud seeking input.
>
> Now that the functionality exists, it's easy to change its syntax. This is
> what
> Open Source software is about, isn't this great? Ideas implemented, improved
> and furthered.
>
> --
> Jeremy Cowgar
> <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a>
Blending in better is a mixed blessing, because what elsif or else means is to
be checked at the master if statement level. For very short code, it hardly
matters, but it doesn't hlelp clarity.
I think I like ifdef better, even if elsifdef looks awkward. After all, it will
be the les used keyword in the group, so it may not matter much. Perhaps to such
an extent that we will hardly need it, so that we'd write
ifdef WINDOWS then
...
elsedef
ifdef DOS then
--
else -- LINUX then
--
end ifdef
end ifdef
if we don't want elsifdef.
CChris
CChris
14. Re: New keywords: ifdef, elsifdef, end ifdef
Jeremy Cowgar wrote:
> I like elsif better and it would reduce one keyword count, but I'm not sure
> about it's clarity? Also, it would then blend in better with other standard
> if/elsif/end if statements? Thinking aloud seeking input.
That sounds like optimization:
Consider, in binding an executable that has the condition involving platform()
comparing to a constant. For the interpreter this is an expression that could
change from execution to execution, but for the program that makes the binary
it will be a constant in the target executable. So, it can optimize out the
stuff that is for Windows if you are binding for a Linux program.
EUPHORIA expressions involving no functions always give you the same value if
they contain only constants. That can be the criteria for whether the binder
should evaluate the expression itself and optimize accordingly.
Shawn Pringle
15. Re: New keywords: ifdef, elsifdef, end ifdef
Shawn Pringle wrote:
>
> Jeremy Cowgar wrote:
>
> > I like elsif better and it would reduce one keyword count, but I'm not sure
> > about it's clarity? Also, it would then blend in better with other standard
> > if/elsif/end if statements? Thinking aloud seeking input.
>
> That sounds like optimization:
>
>
> Consider, in binding an executable that has the condition involving platform()
> comparing to a constant. For the interpreter this is an expression that could
>
> change from execution to execution, but for the program that makes the binary
> it will be a constant in the target executable. So, it can optimize out the
> stuff that is for Windows if you are binding for a Linux program.
>
> EUPHORIA expressions involving no functions always give you the same value if
> they contain only constants. That can be the criteria for whether the binder
> should evaluate the expression itself and optimize accordingly.
>
> Shawn Pringle
For most uses of ifdef and its ilk, the performance difference will be so small
as to be completely unnoticeable. I mean, you're not going to usually do an ifdef
around a critical loop.
Well, you might...
The main thing I see is that conditional interpretation can help version-proof
the language among other things.
If I am thinking correctly, anything that doesn't pass an ifdef test is
considered a comment by the interpreter and is discarded.
A small feature, but seemingly useful.
--
A complex system that works is invariably found to have evolved from a simple
system that works.
--John Gall's 15th law of Systemantics.
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.
16. Re: New keywords: ifdef, elsifdef, end ifdef
Shawn Pringle wrote:
>
> That sounds like optimization:
>
It's much more than that. It's the ability for conditional includes. It's the
ability to remove code from bound or executable code you may not want in there
(such as shareware/full), It gives you the function of even being able to
maintain backwards compatability! Say for instance 4.1 comes out and 4.1 defines
a new function called fast_find or who knows what. You can now:
ifdef EU400 then
global function fast_find(...)
end function
end ifdef
All sorts of other things.
Imagine this:
while 1 do
if debug = 1 then
puts(1, "Reading xyz...\n")
end if
-- code
end while
Well, before you ship your app, you should remove all your if debug = 1
statements. Now look at:
while 1 do
ifdef debug then
puts(1, "Reading xyz...\n")
end ifdef
-- code
end while
Now, run your app: exwc -D debug myapp.ex or translate: ecu myapp.ex That loop
may run 100,000 times in your application. Hm, in fact, I have that in a web app
that is small time and it takes about 8 million hits a month now to the dynamic
side of the app. Granted, that's not big, but, it's not a for 1 = 1 to 10 loop
either.
--
Jeremy Cowgar
http://jeremy.cowgar.com
17. Re: New keywords: ifdef, elsifdef, end ifdef
Jeremy Cowgar wrote:
>
> Shawn Pringle wrote:
> >
> > That sounds like optimization:
> >
>
> It's much more than that. It's the ability for conditional includes. It's the
> ability to remove code from bound or executable code you may not want in there
> (such as shareware/full), It gives you the function of even being able to
> maintain
> backwards compatability! Say for instance 4.1 comes out and 4.1 defines a new
> function called fast_find or who knows what. You can now:
>
> }}}
<eucode>
> ifdef EU400 then
> global function fast_find(...)
> end function
> end ifdef
> </eucode>
{{{
>
That would have been useful when win32lib.ew put a string type in their library.
What I meant by my previous post was you could blend the if and ifdef by
having the truth value evaluated when you the program gets bound. Then you
don't need ifdef. You could have a version() builtin to get a version number
18. Re: New keywords: ifdef, elsifdef, end ifdef
Shawn Pringle wrote:
>
> That would have been useful when win32lib.ew put a string type in their
> library.
>
> What I meant by my previous post was you could blend the if and ifdef by
> having the truth value evaluated when you the program gets bound. Then you
> don't need ifdef. You could have a version() builtin to get a version number
I think we are running into a limitation of what can be done, feasibly. I see
your point, however, I think it's nearly impossible w/out some huge rewrites.
Currently nothing can be executed until the whole app is translated into IL code.
So, functions that return values or dynamic if statements are currently out of
the question for the potential of omitting code. A new keyword was needed that
would do very limited decision making based on values that are known at parse
time, hence the defined words that are handled at parse time via command line and
using the with keyword (which is a parse time keyword as well).
--
Jeremy Cowgar
http://jeremy.cowgar.com
19. Re: New keywords: ifdef, elsifdef, end ifdef
Shawn Pringle wrote:
<snip>
> That would have been useful when win32lib.ew put a string type in their
> library.
Wait,, there's a string type in win32lib??
Kat
20. Re: New keywords: ifdef, elsifdef, end ifdef
Kat wrote:
>
> Shawn Pringle wrote:
>
> <snip>
>
> > That would have been useful when win32lib.ew put a string type in their
> > library.
>
> Wait,, there's a string type in win32lib??
type w32string Implements an ASCII string.
Mike
21. Re: New keywords: ifdef, elsifdef, end ifdef
Mike777 wrote:
>
> Kat wrote:
> >
> > Shawn Pringle wrote:
> >
> > <snip>
> >
> > > That would have been useful when win32lib.ew put a string type in their
> > > library.
> >
> > Wait,, there's a string type in win32lib??
>
> type w32string Implements an ASCII string.
>
> Mike
Sorry to nitpick, but...
I'll change this doc entry anyway. User defined types in Eu hardly implement
stuff, they just recognise it. A w32string is a plain sequence the contents of
which are printable or control single byte chars. It doesn't implement char[] or
TCHAR[] as such.
btw I may consider tagging some user ctypes as printable, so as to allow DBCS
chars in w32strings. Will be in 70.4a if it's delayed enough
CChris
22. Re: New keywords: ifdef, elsifdef, end ifdef
CChris wrote:
>
> Mike777 wrote:
> >
> > Kat wrote:
> > >
> > > Shawn Pringle wrote:
> > >
> > > <snip>
> > >
> > > > That would have been useful when win32lib.ew put a string type in their
> > > > library.
> > >
> > > Wait,, there's a string type in win32lib??
> >
> > type w32string Implements an ASCII string.
> >
> > Mike
>
> Sorry to nitpick, but...
>
> I'll change this doc entry anyway. User defined types in Eu hardly implement
> stuff, they just recognise it. A w32string is a plain sequence the contents
> of which are printable or control single byte chars. It doesn't implement
> char[]
> or TCHAR[] as such.
>
> btw I may consider tagging some user ctypes as printable, so as to allow DBCS
> chars in w32strings. Will
> be in 70.4a if it's delayed enough
I downloaded the latest win32lib off the user contribs page, and did a
wordsearch in it for w32string, and found it is a type. Nothing uses it, nothing
manipulates the w32string in memory. Nothing puts a sequence into memory, and
nothing moves the w32string into a sequence. Near as i can tell, it's a
type-restricted sequence, not a C-type string in memory.
Not nearly like Bernie's mixedlib.e, which i'll hereby nominate as "should be in
Eu". But with integer values bigger than 32bits, of course.
Kat