1. Last call for new features
- Posted by Ralf Nieuwenhuijsen <nieuwen at XS4ALL.NL> Jan 14, 1999
- 425 views
This is my last attempt to convience Robert and the rest of the Euphorians, we need some new features, will any big program be ever _easily_ possible with Euphoria. The order is not of importance, rather of implementation: (though I did number them from 1 to 10) 1) Direct initialization. Simple: integer x = 5, y = 6 2) Arrays. Why? We have sequences. Yes, I know, but sometimes I want to be able to have a sequence of fixed-length. type char (integer x) return x >= 0 and x <= 255 end type char text[20] -- Allocate room for 20 characters Speed benefits: graphics in native Euphoria will now match up with things like mem_copy () and mem_set (). The dynamic allocation and deallocation is great, but when I dont need then, they slow everything down with every slice. Example: image[y][x] First it checks the boundries for y, then it looks up the pointer it points to. Then it checks the boundries for x, then it looks up the value that points to. That value is returned. Now the same with arrays. One multiplication, one boundry check, one value looked up. With hard-typed constants or values, the speed benefit is even more. For example: image[102][203] It can then, during pre-proccesing, lookup the exact memory address and check the boundry. It would be as fast as a normal variable. And it off course increases readability, stability, and it saves us a lot of time. Compare these two: -- Currently with Euphoria you need to do: constant TRUE = 1, FALSE = 0 type char (integer x) return x <= 0 and x >= 255 end type type text (sequence s) if length(s) != 20 then return FALSE end if for index = 1 to 20 do if not char(s[index]) then return FALSE end if end for return TRUE end type text name name = repeat (' ', 20) -- I want to be able to do: type char (integer x) return x <= 0 and x >= 255 end type char name[20] = repeat (' ',20) 3) Structures, though no special tricks, just the plain simple and readable: -- Example of how I would like to see structures implemented structure person do char name[] = "" integer age = -1 end structure Now, I will explain a few things of what you see. First of all, char name[]. It looks like an array, and it is. But its a non-fixed length array. (a sequence thus, every says, irritated: yes, true, a sequence, however still a fixed number of dimensions and one generic type associated to each *element* of the sequence. Secondly, you must have noticed that I initialize all elements of the structures. This is because its a pain, to initialize a structure yourself. This is thus the default initialization. However to use the structure, you must first use it as if it was a type: (actually, it is) person client client[name] = "Ralf Nieuwenhuijsen" client[age] = 16 Again, like with arrays, structures have the advantage they speed things up alot. They are more readable. Prevent half of all the scope problems and enable an easy way to have seperate type-checking-functions for several elements of a sequence. 4) Length should be assumed when its not used in an slice operation. Example: image[4][10..] -- Should read as: image[4][10..length(image[4])] This also prevents many issues, that arise when you would introduce this slicing syntax: image[10..][10..] Crops the image from (10,10) to (end, end) 5) We should be able to assign an sequence to a sequence: {x, y, c} = cursor () Even, the & operator should be supported: {{x,y}} & text = get_text_and_location () This enables much faster proccesing. Its much more readable. And prevents the need for extra variables, and thus prevents scope issues. 6) The scope rules. First of all, there is no person on this planet who started with Euphoria and realized/knew that indirectly half the world included, when you use include. If I used include, only those global identifers in that include files should be available to me. When I include graphics.e but not machine.e, the global routines, constants and variables of machine.e should not be available to me. Overriding of any identifer not defined in my the same include file should only produce a warning. Thus overriding of constants, variables and of routines. When two files include each other, all global indentifers of both files should be available to both files. Mutal recursion between two routines from seperate include files should thus be natively possible, without using routine pointers thus. 7) Euphoria can be faster. Esspecially IO is not as fast as it can be. A simple built-in function like "read_textfile ()" (vs read_bitmap) would be very clean, and fast. Secondly, all input and output that Euphoria does, is better off handeling natively with atoms, than using standard watcom routines, and give them converted data. A puts () should have no need to convert its datatype. A gets () as well. How to achieve that ? By using less watcom routines and more euphoria libraries. I mean, many 'built-in' things could just as easily have been Euphoria files. An great example is the dir95, that is actually better than the one stored in one of the watcom libraries linked with the interpreter. In other cases, just avoiding translation of atoms into bytes can be an huge speed gain. I esspecially mean file IO in this light. Built-in (read: fast) support for ports, wouldnt hurt any one either. Wait retrace is for example a full machine code piece, because using the 'constructed' ports routines were just too slow. Another reason to avoid watcom routines are errors. Things like puts (1, "Hello" & 0 " & " you there") where " you there" is not displayed, since a zero is used to indicate an end-of-line in C. 8) Rather than short-cirquiting, I would like to see smart support for lazy routines. Whenever a function does not *set* any local variable (variables declared in the space of the include file), it should be marked as 'lazy'. Which means, that, when that function is called, rather than actually executing the code, a pointer to the code is stored, until the value is really needed. Example: proceduer display_text (sequence text, boolean should_i) if should_i then for index = 1 to length(text) do puts (1, text & '\n') end for end if end procedure display_text (read_textfile ("readme.txt"), FALSE) It doesnt even attempt to open "readme.txt" since the return value of the function read_textfile is assigned to 'text' in the procedure "display_text". However, during run-time the value is not 'looked'-up. If I say: display_text (read_textfile ("readme.txt), TRUE) Just before the first puts () statement in "display_text", the function read_textfile () is called and the file is opened. This could be done for Euphoria routines, but also for the built-in routines, like find () and operational and math operators. We do not need to perform a multiplication, when there result will be never used anyway. However, this nifty lazy routine system, does not have to complicate anything for the programmer. The interpreter can determine by itself, when a function can be safely marked as 'lazy'. All functions that do not *modify* external variables(variables declared outside of the scope of the function) can be marked 'lazy' without any possible problem or conflict. Off course it may not call non-lazy function as well. Those functions that do call non-lazy routines are non-lazy themselves. But if it is supported, why not, give the programmer the freedom ? Yes, it should be able. But only for those interested in the issues that it may give you (and the power). Just a special keyword can force either mode: lazy function blabla () -- only called when value is read -- you can now keep track of the amount of times, the return value of this function is actually used. end function .. and .. strict function blabla () -- immidiately called -- we might not use any external variables, but we do a windows call for a message (for example), so we want it to be executed immidiately. end function With all other functions, the interpreter can determine wether or not it is safe or not. The speed gain will be great for certain programs. 9) Bind and shroud should have NO issue whatsoever. Even at the cost of run-time speed, may they never ever have any issue. 99% of all programs that people sell, give and/or spread is binded. The whole point of programming is making a program. There should be no issue whatsoever. 10) Whenever *possible* routines should be platform-generic. I mean: mouse-routines, graphics, message-boxes, etc. can have a counterpart on the other platform.... and there _should_ be one. Thats all I can come up with. I would love to see more ideas of other users. So please respond, or post your ideas. (maybe enumeration.. although Im not sure how I would like to see it implemented). And Robert, of all of the above points, as I know some (like structures) are supported by many, could you explain the direction you want Euphoria to take, and why we can or can not expect the above changes to actually happen ? Also, what will the new version offer ? And can we pre-register, when you release the alpha version ? My excues for any language error in the above. Im not a native English spoken person, however do appriciate comments. Ralf Nieuwenhuijsen nieuwen at xs4all.nl ralf_n at email.com
2. Last call for new features
- Posted by Alan Tu <ATU5713 at COMPUSERVE.COM> Jan 13, 1999
- 423 views
- Last edited Jan 14, 1999
Ralf, These are the points I do feel strongly about. >4) Length should be assumed when its not used in an slice operation. >Example: > image[4][10..] > -- Should read as: > image[4][10..length(image[4])] I completely agree. You don't know how many times I've written very much= nested and ugly code that included things like this. >6) The scope rules. First of all, there is no person on this planet who >started with Euphoria and realized/knew that indirectly half the world >included, when you use include. If I used include, only those global >identifers in that include files should be available to me. When I >include >graphics.e but not machine.e, the global routines, constants and >variables >of machine.e should not be available to me. Why should you care? To implement this, a new level of complexity would = be necessary in the interpreter. Did this include come from a source or an include? What about two inclues with machine.e -- one from the include a= nd one for the source. My point is: enforcing this is totally unnecessary a= nd opens up a can of worms! >7) Euphoria can be faster. Esspecially IO is not as fast as it can be. A= >simple built-in function like "read_textfile ()" (vs read_bitmap) would >be >very clean, and fast. This part of your point revives the old debate, especially from some who come from the QBasic world. What about an ABS function, or an LTRIM function, or an RTRIM function, or god knows what function. I've written= functions to read in files as sequences. I agree that there should be an= exp function, and a sqr function (which is there already). But some functions are left for the programmer, unlike QBasic which seems to striv= e to serve every function which one can ever want on every whim, prior to t= he person wanting it. So many in-coded functions or so many machine_func/machine_proc which leads to include files would lead to clutter, not to mention clutter in the docs. >10) Whenever *possible* routines should be platform-generic. I mean: >mouse-routines, graphics, message-boxes, etc. can have a counterpart on >the >other platform.... and there _should_ be one. Again, I completely agree. There's no good reason why things like sound(= ) shouldn't have a WIN32 equiv. On the other hand, some things may not be physically possible with WIN32, namely I'm thinking of tick_rate(). = Message_box() would be really nice in DOS32, but its feeble in WIN32 as i= s. Can you think of any DOS program that would need to display a dialog box= with a question mark icon, if you know what I mean. Alan =
3. Re: Last call for new features
- Posted by Ralf Nieuwenhuijsen <nieuwen at XS4ALL.NL> Jan 15, 1999
- 443 views
Alan Tu wrote: >>6) The scope rules. First of all, there is no person on this planet who >>started with Euphoria and realized/knew that indirectly half the world >>included, when you use include. If I used include, only those global >>identifers in that include files should be available to me. When I >>include >>graphics.e but not machine.e, the global routines, constants and >>variables >>of machine.e should not be available to me. > >Why should you care? To implement this, a new level of complexity would be >necessary in the interpreter. Did this include come from a source or an >include? What about two inclues with machine.e -- one from the include and >one for the source. My point is: enforcing this is totally unnecessary and >opens up a can of worms! Alan, im closing a can of worms rather than opening one. And if you ever try a really big program/project you would know exactly what I mean. An example: I cant use font.e and neil.e together. I cant use neil.e and graphics.e together. Why ? Conflicting identifers. Any human would understand that the file that includes Neil rather that Graphics.e should use the neil-routines, and should have no acces to the identifers in graphics.e (else he would have included it himself, since that is 'clean' programming). So, for a human such things make sence, but the interpreter gets all confused. But what for a human is more simple, is, you are right, complex in the interpreter. But isnt that the reason why we have an interpreter ? Otherwise we could just be programming in ASM. Alan, have you ever tried to program an oop-based library ? I mean, without conflicting class-properties... Why ? Because Euphoria only knowns three scopes. Local to a routine, local to a file, global. In other words, if jiri's font engine defined 'CLEAR' as a constant, and Neil as well. I cant use both! (I had too hack jiri's font, since I understand Euphoria better than Neil's mixture of machine code and Euphoria code) Im not saying doing a: include neil.e include font.e Stops the problem. It shouldnt. But when I have a file that does all kinds of widgets, and uses routines defined by me, and the font library. Should there be a conflict because those routines of me, use Neil ? No, because I didnt include Neil in *that* file. Only in the file that uses it. Im completely suprised that you are actually saying this is more complex. Include in Euphoria currently means: Activate/Execute the local code, and have the global identifers accesable (and possibly conflicting) to all files loaded from this point on. Ignore any futher request to include this file. I want to make the definition like this: Active/Execute the local code, and have the global identifers accesable (and possibly conflicting) to only those include files, that are actually including it. Any futher request to include this file, only means, making the global identifers accesable. It means that for each include file, you can be certain, only YOUR OWN global identifers can conflict. And honestly, that are enough problems for now. Alan, if I gave you a choice between: include graphics.e and everything graphics.e includes, and everything they include, and everything they include .. bla.. bla.. and try to put all global identifers in the same scope, and all accesable to me, and any futher include file, that did not ask for it. Conflict. Conflict. Conflit. Conflit. Conflit. Or, just: include graphics.e Since, currently an include statement should be read as the long definition above. Secondly, its much more in line with many languages. Modula for example. While the current scope is basic scope. And indeed, has basic-like issues. >This part of your point revives the old debate, especially from some who >come from the QBasic world. What about an ABS function, or an LTRIM >function, or an RTRIM function, or god knows what function. I've written >functions to read in files as sequences. I agree that there should be an >exp function, and a sqr function (which is there already). But some >functions are left for the programmer, unlike QBasic which seems to strive >to serve every function which one can ever want on every whim, prior to the >person wanting it. So many in-coded functions or so many >machine_func/machine_proc which leads to include files would lead to >clutter, not to mention clutter in the docs. Alan, there is currently only *one* program that does not load and store the whole file in one pass. All other programs, load and store the whole file at once. It would be an enourmous speed benefit. And it provides cleaner code. Off course, we could make it ourselves, but then we would be "dynamically building a sequence, checking for -1 every cycle" in other words: slow. And yes, we need to do some routines ourselves. But we have routines for wildcard matching, sorting, etc. We have extensive IO routines, but not just the one simple, fast and clean: "read_textfile". Considering the way euphoria handles IO, there is a need for this. >>10) Whenever *possible* routines should be platform-generic. I mean: >>mouse-routines, graphics, message-boxes, etc. can have a counterpart on >>the >>other platform.... and there _should_ be one. > >Again, I completely agree. There's no good reason why things like sound() >shouldn't have a WIN32 equiv. On the other hand, some things may not be >physically possible with WIN32, namely I'm thinking of tick_rate(). >Message_box() would be really nice in DOS32, but its feeble in WIN32 as is. > Can you think of any DOS program that would need to display a dialog box >with a question mark icon, if you know what I mean. Yes, but its just the idea. Maybe in dos, it should just puts () out the text or something like that. Thats not the issue. I just mean, that we should keep as much platform-independent as possible. Ralf
4. Re: Last call for new features
- Posted by Alan Tu <ATU5713 at COMPUSERVE.COM> Jan 15, 1999
- 446 views
Ralf, I see your point about scope now. Thanks for taking the time to explain it. About the routines thing. I agree IO should be improved, but I have a fe= w questions. prompt_number and prompt_string have now been added. Routine= s like this, doesn't this go against the purist atoms and sequences? As a principle, I agree with you about platform-dependent routines. = However, some implementing may be difficult. Alan =