January 18, 2003 Re: "Hi" questions about features not included | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Yokomiso | > > One of the main advantages of a JIT compiler is that it can perform > whole-world optimizations, deciding which methods may be inlined, which > methods are truly dynamic, etc.. Every libray loaded goes through this > process. A static compiler that generates dlls must provide the worst case > binary. As a side note Portable Net interpreter (www.dotgnu.org for more > info) is sometimes faster than JIT compilers from Mono or DotNet, because it > doesn't try to analyze and JIT things first, it just interprets it as fast as it can. > it's all about compromise and what your code is doing and how you distrubute your app. single code path, no matter how long, that executes once will always be fastest if statically compiled here also a plain interpreted will out preform a jit or dynamic compiler becuase there is no compilation or or profile data gathering overheads to consider. however, these are rare condition in most code. for realtime apps, jits are also a pain, a plain interpreter will execute the same code in the same time every time. interpreted langs are also a pain for deployment, you either have to distribute your VM/compiler with the app or rely on people already having it. c# on NT4/win98/2K for instance where clr is not part of the OS. Java on any OS or browser where some are 1.1.x some are 1.4.x memory too, plain interpreters need little extra memory, Jits can be quite memory hungry both the bytecode and the compiled code are required at times, and the compiler itself will require more as it compiles. dynamic compilers (especially those that support code deletion) can operate with much lower memory requirement than jits but usually require more than interpreters to run the same code allthough once you start aggressive inlineing ... well I'm sure you see a pattern. and if you have very compact bytecode, and a very small VM then an interpreter can use less memory than a statically compiled app. Mike. |
January 18, 2003 Re: multiple function return values. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Scott Pigman | You'd need a tuple construct in the language. I think it's a good idea. Sean "Scott Pigman" <scottpig1@attbi.com> wrote in message news:b0ahpt$o5l$1@digitaldaemon.com... > > >> multiple return values from a function. personally, i've never been very > >> keen on the C/C++ idea of having parameters that are actually return values. i like the python model here: "a,b,c = foo(x,y,z)". again, i think it's a lot easier to follow code that has all the inputs in one place and the outputs in another. i guess this wouldn't be compatibly with the IDL like the current in/out/inout specifiers, but i'd say that it's a lot more often that you'd write a function w/ multiple return values than write something that needs to be compatible w/ IDL. and no, i > >> wouldn't suggest getting rid of the in/out/inout specifiers, i'd just rather not use them myself all that often. > > > > Sweet. Hm. Not a real problem, just a decision question. It could make the result be placed on stack, not returned imlicitly by reference, which makes it impossible to call legacy functions this way, but > > why does it make impossible to call legacy functions? actually, what do you mean by legacy functions - embedded C functions i presume? their can't be much of any D legacy functions yet. > > > might... be good for something. Opinions? And inout would simply mutate back to what they are - references? > > > > But what if you use such a function in an expression - you get a real mess. Noone forces though. > > i don't think that's necessary - the expression would use only the first returned value. > > i think it'd go something like this: > > int,int,int foo() > { > return 1,2,3; > } > > a,b,c = foo() // a == 1, b == 2, c == 3 > d = foo(); // d = 1, the second & third return values are lost > > x = foo()*foo() // x = 1 (1 * 1), the other values are ignored. > > > hmmm, how about this construct? > foreach x in foo(){ print x} // prints "1 2 3" > > scott |
January 18, 2003 Re: "Hi" questions about features not included | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Yokomiso | "Daniel Yokomiso" <daniel_yokomiso@yahoo.com.br> wrote in message news:b0apv1$s9u$1@digitaldaemon.com... > With HOFs we can do this. Deimos Template Library > http://www.minddrome.com/d/deimos/deimos-0.0.1.zip provides all, any and > none quantifiers (I think they're in this release) for arrays as template > functions, so you just write: > > public boolean isOdd(int n) { > return n % 2 != 0; > } > instance TArrays(int) arrays; > const int[] numbers = ...; > if (arrays.all(numbers, &isOdd)) { ...} > if (arrays.any(numbers, &isOdd)) { ...} The function call to isOdd needs to be eliminated. That's why closures and anonymous functions are so important, so stuff like this can be inlined. The basic idea is to pass *the function*, or a reference to it, not a pointer to the function, as a parameter. Taking a pointer guarantees it must live at a memory address which is not what you want. Also I personally would replace return n % 2 != 0 with return (n & 1) != 0 so that you can be reasonably sure you'll get the best performance possible. Integer modulus can be very slow. Several orders of magnitude slower than binary and. Sean |
January 19, 2003 Re: "Hi" questions about features not included | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@directvinternet.com> escreveu na mensagem news:b0c76g$1nd8$1@digitaldaemon.com... > "Daniel Yokomiso" <daniel_yokomiso@yahoo.com.br> wrote in message news:b0apv1$s9u$1@digitaldaemon.com... > > > With HOFs we can do this. Deimos Template Library > > http://www.minddrome.com/d/deimos/deimos-0.0.1.zip provides all, any and > > none quantifiers (I think they're in this release) for arrays as template > > functions, so you just write: > > > > public boolean isOdd(int n) { > > return n % 2 != 0; > > } > > instance TArrays(int) arrays; > > const int[] numbers = ...; > > if (arrays.all(numbers, &isOdd)) { ...} > > if (arrays.any(numbers, &isOdd)) { ...} > > The function call to isOdd needs to be eliminated. That's why closures and > anonymous functions are so important, so stuff like this can be inlined. The basic idea is to pass *the function*, or a reference to it, not a pointer to the function, as a parameter. Taking a pointer guarantees it must live at a memory address which is not what you want. Also I personally > would replace return n % 2 != 0 with return (n & 1) != 0 so that you can be > reasonably sure you'll get the best performance possible. Integer modulus can be very slow. Several orders of magnitude slower than binary and. > > Sean > Hi, That's why I, in every other post I write, talk about anonymous functions. I personally like the anon(n) syntax, with or without simple type inference support. But I don't agree that a call to &isOdd and anon(n) {return n % 2 != 0;} are so different that only the closure can be inlined. If the compiler can statically determine the function reference then it can inline it too. Also a closure is not different than a variable bound to a closure. But currently D doesn't offer anonymous functions, so I must provide code snippets using function pointers. A code snippet that uses invalid syntax or semantics is almost meaningless to the reader, except as critics to language constructs. The remark about using (n & 1) != 0 instead is flawed in my opinion. Of course in a simple code snippet it can be clear, but these kind of things are likely premature optimization and may lead to highly obfuscated code. IMO a better code would read "return n.isDivisibleBy(2);" using an OOish syntax, or even "return 2.divides(n);". If we have a language with different idioms for writing code, like use this if you want to be clear, but use that when you want performance, we'll end up doing C/C++ like code. In D we already have this dissension on code snippets about array iteration, just compare those I write versus Burton code snippets. I'm not claiming superiority here, just saying that if we need two idioms for performance reasons, there's something wrong about the language spec. It's like recursion vs. iteration. usually recursion is simpler to understand, but people argue that it's inneficient, so use iteration instead. Most functional languages solve this problem by requiring a compliant compiler to optimize tail call in general, leading to better performance for every kind of tail call, recursive or not. Best regards, Daniel Yokomiso. "All must fall, and those who stand the highest fall hardest." - Phyrexian Scriptures --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.443 / Virus Database: 248 - Release Date: 10/1/2003 |
January 19, 2003 Re: "Hi" questions about features not included | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Yokomiso | "Daniel Yokomiso" <daniel_yokomiso@yahoo.com.br> wrote in message news:b0cqgg$2302$1@digitaldaemon.com... > > The function call to isOdd needs to be eliminated. That's why closures > and > > anonymous functions are so important, so stuff like this can be inlined. The basic idea is to pass *the function*, or a reference to it, not a pointer to the function, as a parameter. Taking a pointer guarantees it must live at a memory address which is not what you want. Also I > personally > > would replace return n % 2 != 0 with return (n & 1) != 0 so that you can > be > > reasonably sure you'll get the best performance possible. Integer modulus > > can be very slow. Several orders of magnitude slower than binary and. > > > > Sean > > > > Hi, > > That's why I, in every other post I write, talk about anonymous > functions. I personally like the anon(n) syntax, with or without simple type > inference support. But I don't agree that a call to &isOdd and anon(n) {return n % 2 != 0;} are so different that only the closure can be inlined. > If the compiler can statically determine the function reference then it can > inline it too. Also a closure is not different than a variable bound to a closure. But currently D doesn't offer anonymous functions, so I must provide code snippets using function pointers. A code snippet that uses invalid syntax or semantics is almost meaningless to the reader, except as critics to language constructs. Gotcha. > The remark about using (n & 1) != 0 instead is flawed in my opinion. Of > course in a simple code snippet it can be clear, but these kind of things are likely premature optimization and may lead to highly obfuscated code. One man's obfuscation is another man's beauty. It's perfectly clear. I guess some programmers don't understand binary arithmetic... I won't be working with those kinds of people. ;) I suppose compilers could optimize the integer modulus, but in practice the ones I've checked only do this for powers of two *if both sides are unsigned*. The problem is that the results of the AND will be different from the results of the MOD if the input is negative, so it can't make the optimization. I suppose a *really* smart compiler could look one step further and see that you're only using the result for comparison with zero, and so allow the optimization. I'll believe it when I see it. And of course we have to use fmod for floats; God evidently forbade use of the same operator for both integer and floating point division or modulus! It's a veritable Tower of Babel. All of programming is like that. > IMO a better code would read "return n.isDivisibleBy(2);" using an OOish > syntax, or even "return 2.divides(n);". If we have a language with different Neither of those seem very readable to me. Just longwinded. It's totally hiding the fact that you're trying to get the computer to test if the low bit of the number is nonzero. ;) > idioms for writing code, like use this if you want to be clear, but use that > when you want performance, we'll end up doing C/C++ like code. In D we already have this dissension on code snippets about array iteration, just compare those I write versus Burton code snippets. I'm not claiming As you can tell, I am used to compilers not doing what I would wish them to, and having to spoon-feed them to get them to do what I want. I program video games for a living. I tend to write what I want the compiler to do fairly explicitly, so as to not waste any more performance than necessary. Waste not, want not. > superiority here, just saying that if we need two idioms for performance reasons, there's something wrong about the language spec. It's like recursion vs. iteration. usually recursion is simpler to understand, but people argue that it's inneficient, so use iteration instead. Most functional languages solve this problem by requiring a compliant compiler to > optimize tail call in general, leading to better performance for every kind > of tail call, recursive or not. I think tail recursion optimization is a great idea; every compiler should do it. If anyone ever manages to unify all syntax and style then we'll have reached the point where programmers aren't needed anymore. Until then, I'm going to code for efficiency, and you can code for readability. Unfortunately I'm stuck with C++ for the foreseeable future. Sean |
January 19, 2003 Re: "Hi" questions about features not included | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | Sean L. Palmer wrote:
> "Daniel Yokomiso" <daniel_yokomiso@yahoo.com.br> wrote in message
> news:b0cqgg$2302$1@digitaldaemon.com...
>
>> The remark about using (n & 1) != 0 instead is flawed in my opinion.
>> Of
>>course in a simple code snippet it can be clear, but these kind of things
>>are likely premature optimization and may lead to highly obfuscated code.
>
>
> One man's obfuscation is another man's beauty. It's perfectly clear. I
> guess some programmers don't understand binary arithmetic... I won't be
> working with those kinds of people. ;)
It is not perfectly clear. "Perfectly clear" is a strong statement to make. With your code, upon initial inspection I have to decide "Hey, is this person checking for a value set in a bit field, or are they checking for division by 2?" It shouldn't take me more than a second, but it's just one more thing that I have to work through to understand what your code is actually *doing*. It's only perfectly clear if I immediately know what you're checking for, .isDivisibleBy(2) (for example) is perfectly clear; there's no two ways it could be meant.
Regards,
Chris
|
January 19, 2003 Re: multiple function return values. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | Sean L. Palmer wrote:
> You'd need a tuple construct in the language. I think it's a good idea.
>
> Sean
Request for Tuples seconded.
Evan
|
January 20, 2003 Re: "Hi" questions about features not included | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | All programmers must learn the common idioms in use near them. If you know the idiom, it's perfectly clear. All you people complaining complaining about having to look 3 lines prior in the file to the declaration of the variable, or the comment next to it that says "check if divisible by 2", or seeing an & and not knowing if it's an address of, overloaded address of, bit field extraction, or odd check. Browse info is pretty powerful stuff. You're expected to look up the declarations for things before you use them, unless you already know your way around that code. I truly have worse things to worry about than someone having to take a few minutes to understand someone else's code. I don't think it's possible to eliminate that few minutes, or even reduce it by much. It doesn't take up your entire day, probably a few minutes tops. And it's a few well-spent minutes because during that time you gain understanding. Just glancing at the code isn't very helpful; you won't usually find bugs that way, or understand much of anything. I think this is a fundamental problem with the state of the art in programming languages. I don't know that there is a solution. But telling me not to use bitwise & when I feel it's appropriate is certainly not the solution. What I'm alot more worried about is code where alot of cut and paste has been done, where there are 40 occurrences of *almost* the identical code. It takes 400 times as long to understand that, or to do anything to it without breaking it. Jeez. Friggin pedants. Sean "Chris" <cl@nopressedmeat.tinfoilhat.ca> wrote in message news:3E2A83EB.7040909@nopressedmeat.tinfoilhat.ca... > Sean L. Palmer wrote: > > "Daniel Yokomiso" <daniel_yokomiso@yahoo.com.br> wrote in message news:b0cqgg$2302$1@digitaldaemon.com... > > > >> The remark about using (n & 1) != 0 instead is flawed in my opinion. > >> Of > >>course in a simple code snippet it can be clear, but these kind of things > >>are likely premature optimization and may lead to highly obfuscated code. > > > > > > One man's obfuscation is another man's beauty. It's perfectly clear. I guess some programmers don't understand binary arithmetic... I won't be working with those kinds of people. ;) > > It is not perfectly clear. "Perfectly clear" is a strong statement to make. With your code, upon initial inspection I have to decide "Hey, is this person checking for a value set in a bit field, or are they checking for division by 2?" It shouldn't take me more than a second, but it's just one more thing that I have to work through to understand what your code is actually *doing*. It's only perfectly clear if I immediately know what you're checking for, .isDivisibleBy(2) (for example) is perfectly clear; there's no two ways it could be meant. > > Regards, > Chris > |
January 20, 2003 Re: multiple function return values. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Evan McClanahan | Evan McClanahan wrote: > Sean L. Palmer wrote: > >> You'd need a tuple construct in the language. I think it's a good idea. >> >> Sean I think tuples are anonymous structs, and thus the syntax should be leaned on the structs, rather then on tuples in other languages. Anonymous structs with implicit underlying types. :/ > > Request for Tuples seconded. > > Evan > |
January 20, 2003 Re: "Hi" questions about features not included | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | Sean L. Palmer wrote: > "Daniel Yokomiso" <daniel_yokomiso@yahoo.com.br> wrote in message > news:b0apv1$s9u$1@digitaldaemon.com... > > >> With HOFs we can do this. Deimos Template Library >>http://www.minddrome.com/d/deimos/deimos-0.0.1.zip provides all, any and >>none quantifiers (I think they're in this release) for arrays as template >>functions, so you just write: >> >>public boolean isOdd(int n) { >> return n % 2 != 0; >>} >>instance TArrays(int) arrays; >>const int[] numbers = ...; >>if (arrays.all(numbers, &isOdd)) { ...} >>if (arrays.any(numbers, &isOdd)) { ...} > > > The function call to isOdd needs to be eliminated. That's why closures and > anonymous functions are so important, so stuff like this can be inlined. > The basic idea is to pass *the function*, or a reference to it, not a > pointer to the function, as a parameter. Taking a pointer guarantees it > must live at a memory address which is not what you want. Also I personally > would replace return n % 2 != 0 with return (n & 1) != 0 so that you can be *Any* compiler is smart enough to do that. Even the Tiny C Compiler coming from the obfuscated C contest!!! > reasonably sure you'll get the best performance possible. Integer modulus > can be very slow. Several orders of magnitude slower than binary and. > > Sean > > |
Copyright © 1999-2021 by the D Language Foundation