Hi,
Rusky wrote:Brendan wrote:The alternative exit provided by the caller must be a label in the caller; and all the compiler does is insert a "mov [esp],???" instruction to change the function's return address before doing "ret". Of course if the function is inlined into another function then "return alternativeExit" just ends up being "goto alternativeExit".
...which is exactly the way Option would keep error handling out of the critical path, without introducing labels, making it yet another feature the programmer has to learn.
Show me how to do this with your Option (while still trying to pretend there's no conditional branch on the critical path):
I didn't introduce labels for alternative exists. I stole labels from assembly and C where they were introduced for other reasons (goto and switch/case targets), and then recycled them.
Also note that alternative exits are also supported in assembly language, e.g.:
Code: Select all
speedLimit as const auto = 100
asmfunction x86_32 checkIfTooFast(distance as u32 in eax, seconds as u32 in ebx) (result as bool in eax) {
eax = invoke calcAverageSpeed(eax, ebx, tooFast)
cmp eax,speedLimit
ja tooFast
mov eax,false
ret
tooFast:
mov eax,true
}
asmfunction calcAverageSpeed(distance as u32 in eax, seconds as u32 in ebx, error as exit in ebp) (speed as u32 in eax) {
test eax,eax
je badArgs
div
ret
badArgs:
exit ebp
}
It also means that you can do this:
Code: Select all
speedLimit as const auto = 100
multitarget checkIfTooFast(distance as u32, seconds as u32) (result as bool) {
; Generic function (only used when no suitable assembly found for target machine)
functiondef checkIfTooFast(distance as u32, seconds as u32) (result as bool) {
if(calcAverageSpeed(distance, speed, tooFast) < speedLimit) {
return false;
} else {
tooFast:
return true;
}
; Equivalent for 32-bit 80x86 assembly (only used when compiling for 32-bit 80x86)
asmfunction x86_32 checkIfTooFast(distance as u32 in eax, seconds as u32 in ebx) (result as bool in eax) {
eax = invoke calcAverageSpeed(eax, ebx, tooFast)
cmp eax,speedLimit
ja tooFast
mov eax,false
ret
tooFast:
mov eax,true
}
}
Rusky wrote:Brendan wrote:With unions the programmer has to decide if they want a union or a structure for no reason other than optimising memory layout by hand;
I use unions (and ADTs) for semantic reasons, not for optimization. It conceptually makes sense to say "this is type A or type B, but not both." I don't really care about the optimization.
That's a silly artificial difference. Semantically, a structure is identical to an untagged union (if the union is used correctly).
Rusky wrote:Brendan wrote:It doesn't causes additional/unexpected instructions, or hidden function calls, hidden memory allocations/deallocations, etc in the final executable.
But it does cause larger structure sizes and move members around. What if you had more than just one or two cases in the union, and all of a sudden your variable doesn't fit in a register (or a cache line!)? What if you use the union for parsing some system table? Then the compiler is making extra costs or breaking things without making it visible to you.
What if you write "
a * 4" and the compiler doesn't convert it into a left shift? What if you write "
int myArray[1234] = "hello";" and the compiler doesn't realise the array is never accessed? What if you have a massive "unusedBloat()" function and the compiler doesn't discard it?
How is a structure member co-location optimisation any different to any other optimisation that compilers have been doing for the last 50 years, where the actual behaviour of the program doesn't change at all (other than speed and/or memory usage) regardless of whether the optimisation is done or not?
Rusky wrote:Brendan wrote:I really don't know why beginners have trouble with pointers (I knew 6502 assembly before I was introduced to pointers, and for me it 2 seconds of "what's this gibberish" followed by "D'oh, pointers are just addresses").
It's because you've been cursed with being unable to "see things from the perspective of a beginner learning their first language." Don't believe me? Go ask a computer science teacher.
Perhaps
this might help (first hit on Google searching for "why are pointers hard to understand"). Here's the most relevant part:
"
Most of my students were able to understand a simplified drawing of a chunk of memory, generally the local variables section of the stack at the current scope. Generally giving explicit fictional addresses to the various locations helped.
I guess in summary, I'm saying that if you want to understand pointers, you have to understand variables, and what they actually are in modern architectures."
Rusky wrote:Brendan wrote:not having any idea how a computer's hardware works. Every beginner programming course should begin with a simplified description of RAM and instructions ("RAM is like a grid of boxes where each box contains a number...").
It's this one, but even worse, because that explanation doesn't always help (speaking from experience teaching pointers).
I think that, in some ways, there is no right way to teach programming (at least not programming as it exists today). Some (most?) teachers think it's a good idea to teach students high level programming first, and then move towards low level after. This leads to difficulty understanding low level concepts (as students end up trying to understand low level things in the context of high level constructs).
Some (less?) teachers think it's better to teach from the ground up, starting with low level and then moving towards high level. This leads to difficulty understanding high level concepts (as students end up trying to understand high level constructs in the context of low level things).
For me personally; I think the high level constructs do more harm than good anyway; and the best way to teach programming is to start with low level and then move towards "medium level", and forget about the high level nonsense completely.
More seriously; I see it as an indication that language designers have failed to make programming easier (and have actually made everything far more complex than it ever needed to be).
Brendan wrote:My point is not that you should remove pointers, but that you can't use "it's too hard for beginners" on its own as a reason to avoid something.
My point is that people learn to cope with things, and this changes their perceptions. For example; someone who has become used to polymorphic classes saying that unions make things easier is a little bit like a blind man saying that dyslexia sounds like fun.
To get rid of the "My arm got bitten off by a shark, and you think paper cuts are bad?" problem it's best to look for people who haven't learn to cope with things and haven't had their perceptions changed.
Cheers,
Brendan