r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Core] Discuss core issues

Maxim
14-Jan-2010
[15461]
after a decade I still find new language tricks.  I call it the "temporary 
newbie moment" phenomenon... I've never had these moments in other 
languages.


its like finding a new trick to make your lego stuff stronger while 
having the same shape  ;-)
Steeve
15-Jan-2010
[15462]
case [
	not mark: find myline "text" [none]
	4 <> length? mark [none]
	...

]
Graham
15-Jan-2010
[15463]
not so easily read  ;)
Steeve
15-Jan-2010
[15464x6]
don't think so, matter of habit
is that less readable than a comnination of any/all/case/if ?
And you can align your code. 
CASE hase the most readable structure for complex tests
Why should have demonstrate such obvious thing ?
;-)

fail: [none]
case [
	not mark: find myline "text" 	fail
	4 <> length? mark 				fail
	...

]
*combination
and most of the time, it's the fastest way of doing tests
ALL is slow
Back in time digression...


I have often noticed that it is unemployed as a method for complex 
testings.

In general it's faster and more easily readable than a serie of nested 
if / else.

But to do such, the programmer must know how testings can be complemented 
and other simplification technics.

The novice programmers (whatever the language) often find it difficult 
to do it correctly.

This is probably a gap in computer education. We don't learn anymore 
the basics of Boolean algebra.

At least for me it is an important criterion to determine the general 
level of someone in computer sciences. 
If I see too many nested if / else in a program.
I think the personn lacks of solid foundations in programming.
Maxim
15-Jan-2010
[15470x7]
other languages promote it based on the general suckyness of the 
case statement in most languages.
which act more like switch than rebol`s case
people often forget that IF, EITHER & UNLESS return values
such as 

val: either success? [blue][red]

instead of

either success? [ 
	val: blue
][  
	val: red
]
and either in a compose is very powerfull... cause it allows conditional 
serie content creation).

; when false, an empty block is returned and compose ignores it.

draw-blk: compose [ (either gfx? [ [pen black circle 30x30 ][    
[ ]   ])]


this example is simple but when creating very complex draw blocks 
on the fly, I often have a few cascaded compose blocks, and in some 
cases, the resulting draw block is an empty block even if it takes 
100 lines to get to that.  the language will skip the nested composes 
if an outer condition is false, so in fact, its VERY fast.
oops missing a "]" bracket in the above.
and if you optimize you can do other stuff, but it gets unreadable 
real fast.
Steeve
15-Jan-2010
[15477x2]
It's not really my point here. There are advanced technics in Rebol 
to optimize the code. 
I don't  blame anyone to not know them all (me neither).

I was comparing nested (messy) testings structures vs. flat (readable) 
structures.

And the reason why people use the bad way and not the right way ;-)
of course i was talking about others not Rebolers ;-)
Maxim
15-Jan-2010
[15479x2]
I know, I'm just providing other advanced rebol styles, where we 
can use the language's natural philosophy instead of applying learnt 
patterns. 


if you look at the compose example, its something completely alien 
to all other languages I have used.  Other functional languages probably 
share some of this style, but its not as elegent, or done as macros, 
or the syntax is so obscure as to make it just about impossible to 
understand in 2 mintues.
to have conditional data creation code INSIDE the data is not something 
you see in other languages.  its usually a mess of conditionals which 
try to cover all possible permutations, as you explain... 


here, there is no need since the data's structure itself will represent 
all conditions naturally and directly.


changing the structure of the data doesn't require code rewriting 
cause they are one and the same.
Ashley
15-Jan-2010
[15481]
The optimization I really like is:

	if i = 1 [j: 2]

with:

	all [i = 1 j: 2]

when I'm reading code it seems to parse in my brain better:


 "if i equals 1 ... then ... j becomes equal to 2" vs "i equals 1? 
 j becomes equal to 2"

blocks seem to introduce a mental "pause" when I read code.
Steeve
15-Jan-2010
[15482]
optimization ? it's slower
Ashley
15-Jan-2010
[15483]
Faster according to Carl. I think he had a blog entry on this one. 
Something to do with "all block" being more efficient than "if cond 
block".
Steeve
15-Jan-2010
[15484]
you're right, just tested
WuJian
15-Jan-2010
[15485]
learned a lot :)
BenBran
15-Jan-2010
[15486]
If 
length? none! 
returned none my code would have looked much cleaner
quite a good discussion though.... learning a lot. Thanks.
Maxim
15-Jan-2010
[15487x2]
these are the tidbits we learn along the way.

there seem to be a few common milestones....  when you get to "grasp" 
that words aren't variables... that is usually one of the first big 
ones... and the big one is when you understand what/how binding really 
works.
realizing that a block can hold [ a a a ] and yet each 'a  is actually 
a different value.  ;-)
Gregg
15-Jan-2010
[15489x2]
I think it was Gabriele, or maybe Ladislav that long ago posted an 
INDEX?? function that was "safe". i.e. it wouldn't crash given none. 
There's nothing stopping you from replacing LENGTH? with your own 
version, or creating a LENGTH?? func. 


There are tradeoffs of course. What may seem to make this particular 
piece of code cleaner may have a far reaching impact on other code. 
I don't always agree with Carl's design, but whenever I think he 
did something wrong, particularly early in my REBOL career, I later 
decided he was right. I still think he's wrong about a few things 
though. :-)
And in this case, it's easy to try and see if you like it.

length??: func [series [series! none!]] [
    all [series length? series]
]
Maxim
15-Jan-2010
[15491]
also as a general learning experience.... code written by Carl and 
study it.


its very had to read, cause Carl optimised the word count so its 
ridiculously compact.. but there are a lot of little coding gems 
in some of the patterns he uses.  and it helps a lot to understand 
some of the ideas behind many functions which might look obscure 
or rarely used.
Davide
15-Jan-2010
[15492]
I personally prefer when a function accepts none value and doesn't 
stop with an error but returns none.

The code is more compact and I can write error handler only If I 
really need it.
Maxim
15-Jan-2010
[15493]
AFAICT, this is the general direction which was taken in R3.   :-)
Steeve
16-Jan-2010
[15494]
Not enough though. 

I complain too often that basic functions are sending too many errors 
instead of returning a default value (none is a good one). 
Which would allow a more compact code as you guys noticed.
Gabriele
16-Jan-2010
[15495]
why not just use ATTEMPT if you don't want errors?
Henrik
16-Jan-2010
[15496]
errors are a good thing. forces you to tighten up your code.
Maxim
16-Jan-2010
[15497x2]
R3 changed focus on errors.  indexes pop up less errors, datatypes 
pop up more errors
Thru the years I have come to the same conclusion as Henrik.  I have 
much less error trapping than I used to.  I'd rather have the crashes 
and fix them.
f
ChristianE
20-Jan-2010
[15499]
Everytime I'm writing (slow, but short) code like 

	>> unique append series 'value

or (very fast, but wordy)
 
	>> any [find series value insert series value]
	>> unless find changes 'weight [insert changes 'weight]


I'm wondering whether there's a nicer way to insert a value into 
a series only if it isn't in there yet. Something in the same line 
as ALTER.

This just reeks like the perfect situation for some Guru O'Brian 
or Gabriele D'Enciclopedia to point out that there's already a REBOL 
native which provides exactly that functionality ;-)


On a unrelated side note, I'm wondering if ALTER is missing an /ONLY 
refinement, too:

	>> alter series: [] [1 2] series
	== [1 2]
	>> alter/only series: [] [1 2] series
	** Script Error: alter has no refinement called only
	** Near: alter/only series: [] [1 2] series


Would that be worth adding to R3, I'm thinking about ticketing it 
as a wish in CureCode?
Pekr
20-Jan-2010
[15500]
insert/not-found would be nice :-)
Maxim
20-Jan-2010
[15501]
I've written such a function often.  its much more usefull than ALTER 
in my use... I'
ChristianE
20-Jan-2010
[15502]
I guess additional refinements to a function as fundamental as INSERT 
are a no-go for performance reasons. Probably ALTER/INSERT or ALTER/ONCE 
though:

	>> alter/once [] flag
	== [flag]
	>> alter/once [flag] flag
	== [flag]


See the dance REBOL/View's FLAG-FACE is doing to achieve something 
like that (and a little bit more):

	flag-face: func [
	    "Sets a flag in a VID face."
	    face [object!]
	    'flag
	][
	    if none? face/flags [face/flags: copy [flags]]

     if not find face/flags 'flags [face/flags: copy face/flags insert 
     face/flags 'flags]
	    append face/flags flag
	]
Steeve
20-Jan-2010
[15503]
Agree, ALTER is definitivly useless.

Not the first time someone is asking to change ALTER in a better 
usefull behavior.
Maxim
20-Jan-2010
[15504]
Carl uses ALTER in a few scenarios, for as a toggle mechanism.
Steeve
20-Jan-2010
[15505]
Only him uses that, I guess...
ChristianE
20-Jan-2010
[15506]
Yes, from a logical perspective ALTER behaves like XOR, where often 
one only really needs an equivalent of OR.
Maxim
20-Jan-2010
[15507]
I'd call the function include... and it could work on strings too, 
doing a find
Steeve
20-Jan-2010
[15508]
once
 is good too, it's short, I like shorties
ChristianE
20-Jan-2010
[15509]
INCLUDE in R3 is not a global word, in the code im currently writing

	>> include package/changes 'weight


reads very nice. Sadly, it's signature wouldn't be compatible with 
EXCLUDE, which only allows series and sets as it's second argument. 

The two refinements /INCLUDE and /EXCLUDE though would make ALTER 
more usefull.
Steeve
20-Jan-2010
[15510]
I am more in favor of finding a short name, it's a very common idiom.