[REBOL] Re: [TYPE] weird return value

2004-04-21 Thread Joel Neely

Hello, all...

Consider this:

  reduce [type? /home/http/run/cohen/birds]
== [refinement! /http /run /cohen /birds]

So each element of the path-looking thingie is treated as a distinct
value, and what gets printed is the last one, just as in

  type? 1 2 3 4
== 4

Hope this helps!

-jn-

Hallvard Ystad wrote:

 Hi Tim,
 
 You start with a /, and for some reason, that is recognized as a refinement!, not a 
 path!.
 
type? /home
 
 == refinement!
 
 refinements are (like?) a data type:
 
/home
 
 == /home
 
 But I do agree that type? /home/http/run/cohen/birds should not return /birds.
 
 HY
 
 Dixit Tim Johnson (20.29 21.04.2004):
 
 
this is weird:


type? /home/http/run/cohen/birds

== /birds

/birds is obviously not a type.

What is happening here?
thanks
tim
-- 
Tim Johnson [EMAIL PROTECTED]
 http://www.alaska-internet-solutions.com
-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.
 
 
 Prætera censeo Carthaginem esse delendam
 
 

-- 
As we enjoy great advantages from inventions of others, we should be
  glad of an opportunity to serve others by any invention of ours;
  and this we should do freely and generously.  --  Benjamin Franklin


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Simple XML

2004-03-09 Thread Joel Neely

Hi, Terry,

No script needed.  PARSE-XML does what you're asking (given that
you can use the block convention it creates -- see below).

T. Brownell wrote:
 Is there any available scripts that turn xml into rebol blocks?  So that ...
 

  xml-stuff: {root
 {person
 {name
 {fname
 {Bob
 {/fname
 {lname
 { Smith
 { /lname
 {   /name
 {/person
 {/root}
 == {root
 person
 name
 fname
 Bob
 /fname
 lname
  Smith
  /ln...
  block-stuff: parse-xml xml-stuff
 == [document none [[root none [^/ [person none [^/
[name none [^/ [fname none [^/Bob^/
...

The convention is that each XML element is represented by a 3-item
block, containing:

1)  the name of the element/tag as a STRING!
2)  attributes (as a block of name/value pairs) or NONE if no attrs
3)  contents (as a block of the content items -- strings for text
 and blocks for child elements) or NONE if no contents *AT*ALL*

IgnorableWhiteSpace is not ignored, but appears as STRING! content.

The entire XML string is wrapped in a mythical element whose tag is
the WORD! DOCUMENT with no attributes.  If you juat want the XML
content, just take FIRST THIRD of the result of PARSE-XML, as in
(the line breaks were added for email formatting, and should be
eliminated if you try to cut and paste):

  x: {topmiddle place='between'
   bottomdown/bottom/middle/top}
 == {topmiddle place='between'
   bottomdown/bottom/middle/top}
  print mold first third parse-xml x
[top none [[middle [place between] [[bottom none [down]]
 

HTH!

-jn-

-- 
Single bit errors are corrected. Joel Neely
Double bit errors are detected.  joel dot neely
Undetected errors are ignored. at fedex dot com


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Help with HTTP protocol

2004-03-04 Thread Joel Neely

Hi, Carlos,

Carlos Lorenz wrote:
 
 read http://br.weather.com/weather/tenday/BRXX2888   does not work anymore 
 as expected. 
 

What does it do?  At first glance (using NS7.1) that the
returned page is making heavy use of JavaScript to manage
content.  If that's correct (whether through stupidity or
hostility on the part of weather.com ;-) you may have a much
harder time getting the content you want without a browser
that implements JS (assuming that you don't want to write
your own JS interpreter... ;-)

-jn-

-- 
Joel Neelycom dot fedex at neely dot joel

I had proved the hypothesis with a lovely Gedankenexperiment,
but my brain was too small to contain it.  --  Language Hat


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: MySQL protocol bug

2004-02-19 Thread Joel Neely

Hi, Maxim,

Pardon my being picky, but we can take your point even
further...

Maxim Olivier-Adlhoch wrote:
 
 in rebol, creating a function is an expression! so you usually write:
 
funcname: func [arg] [put your code here]
 

Although we *may* write something like that, when we do so
we are actually combining two distinct concepts in one
expression:

1)  defining a function, and
2)  making a particular word refer to that function.

and the habit of thinking of those two together results in
one of the standard newbie questions:

 How can I find out the name of this function?

which is no more meaninful than asking for the name of a
value of any other type.  (Of course, that's what it means
to say that functions are first-class values...)

 How can I find out the name of 2?

 How can I find out the name of {Hello, world!}?

etc.

 
 Now, how many languages will handle a stray value in code
  without choking...  not even python will let you insert a
  string anywhere in its code, if its not being used by a
  function.
  ...
  python or c would give you a syntax error, because it excepts
  ALL values to be part of a structure, which is defined by
  strict syntax and parenthesis useage.  When it encouters
  bogus data, it just cant handle it, cause it differentiates
  values and functions.  IMHO rebol does not.  They really are
  all just values, even functions.
 

The following (console transcript) shows that one *can* insert
values (e.g. strings) into the body of a Python function when
such values aren't actually used for anything.

  def somefunc (x, y):
... silly function containing pointless string
... x2 = x * x;
... y2 = y * y;
... foo?;
... print x2 + y2;
...
  somefunc (3, 4)
25

One can do similar things in Perl.  The parser will let
you know that the value is not used; surely you don't think
that's all bad???  How many of us have *never* made a typo
in a REBOL script that changed the meaning of something in
a way that produced an error, but the interpreter never
helped us find it?  (However, Perl will still run your
program after whining at you.)

For example, take a largish REBOL script and delete a single
occurrence of '+ somewhere in the middle.

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Shooting yourself in the foot...

2004-02-18 Thread Joel Neely

The expression

 shoot foot

evaluates to NONE because you forgot to use one of the
/BULLET  /ARROW  or /CANNON refinements; however

 shoot/off x

returns a STRING! longer than available memory if X is of
type EMAIL! or MOUTH!

;-?

-jn-

Izkata wrote:
 ooh, hehehe, I'm saving this Anyone know of a REBOL addition?
 
 - Original Message - 
 From: Jason Cunliffe [EMAIL PROTECTED]

 http://burks.bton.ac.uk/burks/language/shoot.htm
-- 

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: oss revisited (briefly!)

2004-02-16 Thread Joel Neely

Hi, Robert,

Robert M. Münch wrote:
 
 ... As I'm doing a lot of software  
 project proposal evaluation for my customers, the first questions to 
 vendors is: Hmm... it's a Java product. Why? Java didn't work on the 
 desktop, why should it on the server?
 

You must have an interesting definition of didn't work!  Just two
examples should suffice: Eclipse (desktop) and WebLogic (server) work
quite nicely.

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: oss revisited (briefly!)

2004-02-13 Thread Joel Neely

Hi, Karl,

Karl Robillard wrote:
 I'm not a Java expert, but I assume that there is a formal specification for
 Java and that there are many implementations (Sun, IBM, Blackdown?).  That
 may explain why people would be comfortable adopting Java but not REBOL.
 

The authoritative page is http://java.sun.com/docs/books/jls/

 The Java Language Specification, Second Edition - Written by the
 inventors of the technology, this book is the definitive technical
 reference for the Java programming language. If you want to know
 the precise meaning of the language's constructs, this is the source
 for you.

 The book provides complete, accurate, and detailed coverage of the
 syntax and semantics of the Java programming language. It describes
 all aspects of the language, including the semantics of all types,
 statements, and expressions, as well as threads and binary
 compatibility.

The entire spec is available on-line in HTML, downloadable in HTML
and PDF (both ZIPped), and orderable in dead-tree form.

Having a definitive specification makes it possible to learn more
efficiently then trial-and-error or ask-somebody-when-stumped, and
also makes it possible to distinguish implementation defects (bugs)
from cases of I-didn't-understand-that-feature.

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: oss revisited (briefly!)

2004-02-13 Thread Joel Neely

Hi, David,

The punch-line (from my perspective) is at the end.

David Feugey wrote:
 
 There are also big issues with portability.
 
 ...  no OSS version of the language means no fragmentation
 of the source code.
 

That simply doesn't follow.  Perl, Python, Ruby, etc. etc. etc.
have been open source from the beginning, and don't suffer from the
oft-threatened specter of fragmentation.  It simply hasn't happened.

What has happened is that those languages are available on a very
wide range of platforms, and are even capable of being embedded into
another program as a macro language, thus providing even more
(domain-specific) platforms where knowing the language can be an
asset.  Ask yourself what benefits there might be to REBOL if a team
writing the next killer app could decide to use REBOL as the built-
in scripting/macro language within that app.

 
 Of course that does not mean that OSS 
 implementations dont have to exist, but just that the main 
 implementation is not and that the other one cannot be called Rebol.
 
 It's the same for Java with Kaffe (for example).
 

No.  Java is a *language*, not an implementation.  It is defined by a
specification, which makes it possible to check whether any specific
*implementation* (Sun's JDK, Kaffe, Jikes, Blackdown, etc. etc.)
correctly implements that spec.

Of course the holder of a trademarked language name for a language
with a published spec is perfectly within rights to insist that the
name only be used with implementations which conform to the spec.

This is *not* parallel to the case of R# and REBOL.  REBOL is an
implementation, without a publicly available specification.  That
means that any effort to create another implementation is based on
inferences, guesswork, etc. etc. etc.  and can't be guaranteed to
match precisely the behavior of the implementation from RT.

Are the current limits on number of global words, depth of recursion,
etc. actually part of the hypothetical spec of REBOL, or are they
just limits of the current implementation?  If the R# team guessed
right on everything else, but allowed more global words or deeper
recursion, would that be correct?  Who's to say?


PUNCH LINE:

Most of the recent discussions re open source are irrelevant, and
there have been many assertions made which are simply contrary to
fact.

REBOL isn't open source because the creator/owner has decided not
to do that.  Period.  And he has a perfect right to choose how to
make the fruit of his labors available to the rest of us.

However, if we're going to discuss the pros and cons of open source
in an attempt to persuade him to change his mind, or to persuade
others on the list that his choice had general benefits, we need to
stick to the facts and look at what has actually happened in the
arena of open-sourced languages.

-jn-


-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: oss revisited (briefly!)

2004-02-13 Thread Joel Neely

Hi, David,

David Feugey wrote:
...  no OSS version of the language means no fragmentation
of the source code.

That simply doesn't follow.  Perl, Python, Ruby, etc. etc. etc.
have been open source from the beginning, and don't suffer from the
oft-threatened specter of fragmentation.  It simply hasn't happened.

 
 It is... When you want to make a GUI with Perl, you have the choice 
 between about 10 toolkits. None of them is standard or widely used 
 (sorry, I call this fragmentation). It's the same for CGI, network, 
 image reading, etc.
 

That has nothing to do with closed-source-vs-open-source issues.  If
two different programmers write, and offer to the world, two different
solutions to the same problem domain, that doesn't mean that THE
SOURCE CODE of the language itself has fragmented (which was the
original complaint).

Andrew's ML dialect is one solution to generating HTML/XML/SGML/etc.
Someone else could come along and write (and give away) a different
solution to that problem.  That isn't fragmentation of the language
itself.

Perl was invented before the time when people considered full-blown
graphics to be a part of a core language.  (Some people still don't
consider that to be so...)  Different people wrote graphic libraries
and frameworks (or adapters to externally-existing libs and fws) for
use in writing graphic applications in Perl.  That doesn't mean that
the language itself is fragmented, any more than the independent
existence of MySQL and Oracle mean that any language that can talk to
both of them is fragmented.

 ...
 
This is *not* parallel to the case of R# and REBOL.  REBOL is an
implementation, without a publicly available specification.  That
means that any effort to create another implementation is based on
inferences, guesswork, etc. etc. etc.  and can't be guaranteed to
match precisely the behavior of the implementation from RT.

 
 Yes, you're absolutely right on this point... specifications should be 
 public.
 

I still believe that this would be the biggest single step toward
facilitating the growth of REBOL.

 
 Pros and cons for both... even if I prefer an OSS model.
 
 But Rebol is pretty good... Appart from the licence (still not clear) 
 it's a good language, and for me it's essential.
 

I agree that it's a good language.  I just want us not to be caught
comparing apples with Thursdays when we talk about the pros and cons
of different distribution/development models.  ;-)

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: oss revisited (briefly!)

2004-02-10 Thread Joel Neely

Hi, Robert,

Just my $0.02 here...  However, let me emphasize that I'm not agitating
for a change of RT position here, but just clarifying what I understand
open source to be about, and some benefits of open source.

Robert M. Münch wrote:
 
 Hi, I never undestand what the problem is? What's the problem with Rebol 
 not being open-source? It doesn't cost hundred-of-thousands of $s to use. 
 So if you are doing things that will create revenue, you can afford a 
 license, if not use the free interpreter.
 

With all due respect, I think you're confusing two distinct issues here.
To paraphrase ESR and RMS, open source is about free as in free speech,
not free as in free beer.  Access to source code is about availability
of knowledge, as expanded below.

 
 But, all those open-source demagogues, if you can show-up with a 
 business-model that let RT make some money from their work, I will be 
 quite but otherwise it's just a techie POV with no business know-how 
 behind it.
 
 And, BTW: Those not caring about Rebol because not being open-source have 
 a problem ;-)
 

Again WADR I think you're contradicting yourself here.  Saying that
something has no value unless somebody can make money off of it seems
just as much advocating a philosophical POV (not to accuse anybody of
demagoguery ;-) as saying that the greatest value to society at large
is obtained by knowledge to be freely available.  As for the other
contradiction, your first paragraph seems to be arguing for a strictly
commercial POV, but your second paragraph seems to ignore the marketing
principle that the customer has the right to decide what (s)he wants.

I know some people who don't care about anything that doesn't run on
Windows.  Do you think they have a problem simply because they have a
preferred platform and delivery model?

RT can make money by providing expert support, just as an engineering
firm can make money by providing expertise, even though that expertise
is based on applying the open source laws of physics which are freely
available to all.  Similarly, legal firms make *LOTS* of money offering
their expertise, even though anyone can legally go to a law library and
read the source code of the laws of the nation.

 
 Well, why not? If someone can tell me a really benefit Rebol being 
 open-source I might change my POV. Sorry, if this sound a bit harsh here, 
 but only moaning without showing a solution is not that professional.
 

1)  Faster bug fixes.  Many folks on this mailing list have offered but
 fixes for mezzanine code, but their/our ability to help debug and
offer corrections hits the wall when natives are involved.  RT produces
good code but nobody is perfect and we know that there have been bugs
which have taken quite a while to resolve due to other priorites and
limits on resources.

2)  Improved documentation.  Many on this list have contributed ideas,
 explanations, and mental models re various features of REBOL.  If
we had access to the source code, those who are willing to invest the
effort to understand the interpreter and/or natives could offer exact
and definite answers for how does REBOL do ... and what does ...
mean in REBOL kinds of questions.  The user community could stop
wasting time trying to guess and/or debate such issues.  Making the
user community more effective certainly benefits both the users and RT!

3)  Faster porting.  There have been several mentions on this list in
 the past few days about the fact that /View on Mac OS/X has been
pending for over a year.  In the open source world, sufficiently-
interested parties can perform (or at least contribute to) the legwork
of getting an existing piece of code ported to another environment
(even if only for beta purposes).

The list could go on, but you asked for a benefit and I've mentioned
three, so I'll stop.  ;-)

Again, let me stress that I'm not complaining or advocating here; RT
has a perfect right to decide what model and license REBOL will be
provided under.  As a user, I simply decide whether I prefer to use
the tool under their model, or live without it.  I certainly agree
that whining and moaning are not professional, but I do believe that
calm, rational discussion of the pros and cons of alternatives is
also legitimate.

-jn-


-- 
Joel Neelycom dot fedex at neely dot joel

I had proved the hypothesis with a lovely Gedankenexperiment,
but my brain was too small to contain it.  --  Language Hat


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Threading continued

2004-01-29 Thread Joel Neely

Hi, Maarten,

Maarten Koopmans wrote:
 
 ... it responds to a 'rest word, giving you the restof the 
 block to be evaluated and the value of the last evaluated expression.
 
 So: eval [ 10 + 10 join a b rest 20 print howdy ]
   [ ab [ 20 print howdy]]
 
 Note that the second item (the rest of the code) is the position in the 
 original code, so a ' head on that gives you the original code back.
 

Sort of like iterating DO/NEXT with an additional check for REST ?

 
 Question: is this a thing any of you want despite the performance hit of 
 400% ?
 

I pondered doing something with DO/NEXT a while back, but gave up in
frustration (I hope you're smarter and/or more patient than I ;-) as
I want to be able to write expressions/functions more sophisticated
than a single block, but still have interruptability.  For example:

 eval [
 foreach line read/lines %somefile [
 print line
 rest
 ]
 ]

Or

 interruptableFunction: func [aLine [string!]] [
 print aLine
 doSomethingInteresting aLine
 rest
 ]

 eval [
 foreach line read/lines %someOtherFile [
 interruptableFunction line
 ]
 ]

You said takes a block so I inferred that things such as the above
(nested blocks, including function evaluation) are currently out of
reach.  Am I too pessimistic?

If I have to do all the work of managing e.g. loops and other control
structures, including functions, I think I'd probably want to just go
ahead and evert the code into a task object (per the article on
REBOLforces) with a STEP method that does some meaningful (but not over
long) piece of work and then saves state and returns control.

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Directory

2004-01-14 Thread Joel Neely

Hi, Chris,

Chris Siegle wrote:
 Why is it I cannot make a directory from an assigned variable name?
 
 testVariable: 12312323
 
 make-dir %testVariable

The argument to MAKE-DIR should be a FILE! or URL! value, not a
STRING! value.

  ? make-dir
 USAGE:
 MAKE-DIR path /deep

 DESCRIPTION:
  Creates the directory structure specified.
  MAKE-DIR is a function value.

 ARGUMENTS:
  path -- (Type: file url)

 REFINEMENTS:
  /deep

 (SPECIAL ATTRIBUTES)
  catch

therefore,

 testVariable: 12312323
 make-dir to-file testVariable

should work for you (assuming you have write permissions in the
current directory).

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: How to remove words from objects?

2004-01-13 Thread Joel Neely

Hi, Luke,

Sorry.

Luke wrote:
 Dear list
 
 I'm trying to dynamically add and remove words from an 
 object...
 

You can't.

 
 now I want to remove c from obj. How do I do that. I 
 know I could dynamically reconstruct it from scratch, but 
 that is not very elegant. There must be a better way to 
 get back to obj being:
 

There's not.

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: How to remove words from objects?

2004-01-13 Thread Joel Neely

Hi, Luke,

Luke wrote:
 
 I dont understand Gregg what you mean when you say 
 the context of an object isnt dynamic... 
 

Once an object has been created, its context (namespace)
is set in concrete and cannot be changed (although the values
to which its words are set *can* be changed).

 
 But if so, then how does that explain why can I do this 
 (but not reverse the action):
 
 ;---create object
 obj: make object [a: 1]
 
 ;---add a new word to the object
 obj: make obj [b: 2]
 

Because you are not adding a new word to *the*original* object,
but instead are creating a *new* object (based on the original)
which contains the new value.  To see that this is not modifying
the original, just consider this:

  obj: make object! [a: 1]
  other: obj
  obj: make obj [b: 2]
  source obj
 obj:
 make object! [
 a: 1
 b: 2
 ]
  source other
 other:
 make object! [
 a: 1
 ]

So the original object is still around (referent of OTHER) but
now OBJ refers to a *new* object.

 

You can get tricky and work around it, by including a block in your
object and using that as kind of a sub-context--because blocks are
resizable. I think Ladislav or Joel posted a dynamic object example
here at one time...


If you want shared references to an object to all show the
effect of such structural changes, you can wrap the object
in another object (i.e. create an additional level of
indirection) which is the common referent:

  wrapper: make object! [
 [inner: make object! [
 [a: 1
 []
 []
  obj: wrapper
  other: wrapper
  source obj
 obj:
 make object! [
 inner:
 make object! [
 a: 1
 ]
 ]
  source other
 other:
 make object! [
 inner:
 make object! [
 a: 1
 ]
 ]
  obj/inner: make obj/inner [b: 2]
  source obj
 obj:
 make object! [
 inner:
 make object! [
 a: 1
 b: 2
 ]
 ]
  source other
 other:
 make object! [
 inner:
 make object! [
 a: 1
 b: 2
 ]
 ]

(Of course, the wrapper could be a block as well, but using
an object as a wrapper allows an easy way to put methods in
the wrapper that delegate to the inner object, so you can
hide the indirection from any client code.)

-jn-

-- 
Joel Neelycom dot fedex at neely dot joel

I had proved the hypothesis with a lovely Gedankenexperiment,
but my brain was too small to contain it.  --  Language Hat


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Is Rebol OO?

2004-01-12 Thread Joel Neely

Hi, Behrang,

Behrang Saeedzadeh wrote:
 
 ... is REBOL Object Oriented?
 

As you can tell from the variety of responses, the question
is a bit tricky to handle.  Unfortunately, the phrase object
oriented has been siezed on by marketers, reporters, comp
sci researchers, methodologists, consultants, and snake oil
salesmen, and given different spins by all of the above.  Let
me duck the phrasing of your original question, and answer a
closely-related one, in the hope that something I say will
address your needs:

 I already know how to program in language XYZ, which
 is commonly regarded as an object-oriented language.
 How much of what I know about programming in XYZ will
 be useful to programming in REBOL?

Answering this modified question would require addressing some
of the following issues:

1)  REBOL is a dynamically-typed language.  This is familiar
 territory if you are used to Smalltalk, Python, or Perl;
 It may take some adjustment if you are used to Java, C++,
 Eiffel, Delphi, etc.  Type errors (attempting to apply an
 innappropriate operation on a value, trying to access a
 non-existent component of an object, etc.) are caught at
 run time, not prevented at compile time.

2)  An object in REBOL is a namespace.  The values associated
 with the words defined in an object represent the state of
 the object, and functions defined (at creation time) within
 the object use those words in the familiar way:

 sample: make object! [
 some-data: Hello, world!
 some-method: func [] [print some-data]
 ]

 Immediately after evaluating the above definition, an
 evaluation of SOME-METHOD results in the output of

 Hello, world!

 regardless of whether there's a word SOME-DATA defined
 anywhere else (e.g. globally, within another object, etc.)

3)  All words defined within an object are public.  That's
 why I had to say immediately after evaluating... in the
 previous point.  Given the above object, you can also say

 sample/some-data: Goodbye, cruel world!

 to change the state of SAMPLE.  There's no built-in way to
 make SOME-DATA private, and inaccessible to the rest of the
 world.

4)  REBOL uses a prototype model of object creation, rather than
 a class-based model or a delegation model.  Objects are made
 one-at-a-time and one-of-a-kind.  You can use a block (as in
 the above example) as a specification for creating an object,
 and can use the same block repeatedly:

 sample-spec: [
 some-data: Hello, world!
 some-method: func [] [print some-data]
 ]

 sample1: make object! sample-spec
 sample2: make object! sample-spec
 sample3: make object! sample-spec

 but once those objects are created, each has a life (state)
 of its own; any resemblance is viewed by REBOL as merely
 coincidental.  In particular, each of the above objects has
 its *own* function named SOME-METHOD .  There's no concept
 in REBOL of instance method shared between the objects.

 You can also use an existing object as a specification:

 demo1: make object! [
 some-data: Hello, world!
 some-method: func [] [print some-data]
 ]

 demo2: make demo1 []
 demo3: make demo2 []

 but, again, a newly created object is like a newly-hatched
 sea turtle; it resembles any siblings which may have come
 from the same parent, but immediatly upon hatching, it must
 face the wild ocean on its own.  It has no parent.

5)  As a consequence of all of the above (and the dynamic nature
 of REBOL itself) you can build your own convenience methods
 to implement some features you may be accustomed to using:

 greeter-class: make object! [

 _greeter: make object! [
 greetee: TBD
 greet: func [] [greeter-class/_greet self]
 ]

 new: func [who [string!]] [
 make _greeter [greetee: copy who]
 ]

 _greet: func [which [object!]] [
 print [Hello, which/greetee]
 ]

 ]

 which provides a constructor (NEW) and a single shared method
 for all instances (GREETER-CLASS/GREET), which defer to the
 class definition...

  world-greeter: greeter-class/new world!
  mom-greeter: greeter-class/new Mom!
  lonesome-greeter: greeter-class/new anybody?

 ...so that each instance uses the common behavior:

  world-greeter/greet
 Hello, world!
  mom-greeter/greet
 Hello, Mom!
  lonesome-greeter/greet
 Hello, anybody?

 Of course this is overkill for something as simple as shown
 above, but if the GREET method were complex and lengthy, it
 would save space to have each instance object contain only
 stub methods 

[REBOL] Re: sort/scramble

2004-01-05 Thread Joel Neely

Hi, Anton,

Anton Rolls wrote:
 
 You might be able to do all this in the sort
 comparator function somehow, but it's not obvious
 to me.
 

I don't believe that it's possible to handle all of this via
SORT/COMPARE .  The comparison function only tells whether
two values are in order or out of order (presumably the basis
for a decision whether to swap them, regardless of sorting
strategy: shellsort, quicksort, heapsort, bubblesort, etc.)
Exchanging two elements (or partitioning the set) based on
a two-element comparison is guaranteed to improve the net
sortedness of the entire collection, without regard for
the rest of the values.  (The elements don't even have to be
adjacent for this to be true!)

The property of a block that says all pairs of adjacent
elements are different for some definition of different
is a global property and can't necessarily be improved by
considering only two values.  If they are the same, then
clearly one of them must be swapped away from the other,
but without taking more of the collection into account, it
is not possible to guarantee that such a swap will improve
the desired condition.  For example:

 ... a b c d e f...

if the values represented by C and D are same for the case
at hand, we MIGHT be able to improve things by swapping B and
C, but only if A and C differ and B and D differ, etc.

I'm not saying that one couldn't create an tuned algorithm to
massage the collection into the desired state, only that I
don't believe there's a way to do it with a sorting function.

-jn-

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: sort/scramble

2004-01-04 Thread Joel Neely

Hi, Hallvard,

To ensure unsorted, first sort, then interleave second and first
halves.  (Assuming you have enough distinct values that moving
halfway through the sorted order gives you a different value.)

Hallvard Ystad wrote:
 
 I have a block with, say 10 blocks inside it. Each block has many
  different data types within it (but only one element matters).
  I want to unsort them so that _part of_  the fourth element (a
  string) is not identical in adjacent blocks...
 
 example: [[4 1 7 nicsrg 5 6 3 8 2 9] [3 1 2 sicrtg 9 8 4 7 6 5]
  [9 3 7 iscgtn 6 2 8 5 4 1] [1 3 8 inctrg 5 2 9 4 6 7]
  [9 6 5 ngsirt 8 2 1 3 7 4] [3 7 8 igtnrs 4 1 2 9 5 6]
  [6 4 8 gnrsit 2 3 9 1 5 7] [9 5 4 sntgir 6 7 8 2 1 3]
  [6 7 4 gstinr 1 5 2 3 9 8] [7 9 2 sgcnit 5 1 8 3 6 4]]
 
 In the first four blocks, the third character in the fourth element
  is #c. I want these four blocks split apart. Getting at the
  character in question is easy (foreach b example [print pick fourth
  b 3]), but unsorting the blocks from there?
 

Let's define (and demonstrate) the interleaving function first:

 riffle: func [b [block!] /local n j result] [
 j: to-integer (n: length? b) / 2
 result: make block! n
 for i 1 j 1 [
 append/only result pick b i + j
 append/only result pick b i
 ]
 if odd? n [append/only result last b]
 result
 ]

Which behaves as:

  riffle [0 1 2 3 4 5 6 7 8 9]
 == [5 0 6 1 7 2 8 3 9 4]
  riffle [0 1 2 3 4 5 6 7 8]
 == [4 0 5 1 6 2 7 3 8]

So that (for a trivial case, which I know is already sorted)

  riffle sort [0 0 0 1 1 1 2 2 2 3 3 3]
 == [2 0 2 0 2 0 3 1 3 1 3 1]

adjacent elements are now different.  Finally, for your example:

   example: [[4 1 7 nicsrg 5 6 3 8 2 9] [3 1 2 sicrtg 9 8 4 7 6 5]
 [9 3 7 iscgtn 6 2 8 5 4 1] [1 3 8 inctrg 5 2 9 4 6 7]
 [9 6 5 ngsirt 8 2 1 3 7 4] [3 7 8 igtnrs 4 1 2 9 5 6]
 [6 4 8 gnrsit 2 3 9 1 5 7] [9 5 4 sntgir 6 7 8 2 1 3]
 [6 7 4 gstinr 1 5 2 3 9 8] [7 9 2 sgcnit 5 1 8 3 6 4]]
   example: riffle sort/compare example func [a b][a/4/3  b/4/3]
   foreach item example [print mold item]

which gives:

   [6 4 8 gnrsit 2 3 9 1 5 7]
   [1 3 8 inctrg 5 2 9 4 6 7]
   [9 6 5 ngsirt 8 2 1 3 7 4]
   [3 1 2 sicrtg 9 8 4 7 6 5]
   [3 7 8 igtnrs 4 1 2 9 5 6]
   [4 1 7 nicsrg 5 6 3 8 2 9]
   [6 7 4 gstinr 1 5 2 3 9 8]
   [7 9 2 sgcnit 5 1 8 3 6 4]
   [9 5 4 sntgir 6 7 8 2 1 3]
   [9 3 7 iscgtn 6 2 8 5 4 1]

where adjacent (sub-)blocks differ in the third character of the
fourth element.

-jn-

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: sort/scramble

2004-01-03 Thread Joel Neely

Hi, Hallvard,

Hallvard Ystad wrote:
 Hi
 
 I need a function that will make sure a block is _not_ sorted.
 

How about this:

  random [0 1 2 3 4 5 6 7 8 9]
 == [8 9 3 4 2 1 7 6 0 5]

Of course, there's a 1 in 3628800 chance that a random arrangement
of ten values will actually be in order!  ;-)

If you really mean *NOT* sorted (and your values are distinct), but
don't care about randomness, then

reverse sort foo

will make sure that FOO is _not_ sorted in ascending order.

Can you provide a little more detail on your requirements?

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] This time of year...

2003-12-22 Thread Joel Neely

...gets quite busy in my world, so let me take this opportunity
to wish all of you a joyous holiday season and a happy new year!

-jn-

-- 
--
Joel NeelymocTODxedefTAyleenTODleoj   6444-362-109


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: a new switch-like flow-control function

2003-12-19 Thread Joel Neely

Hi, Maxim,

There's more to the story, although YMMV...

Maxim Olivier-Adlhoch wrote:
 
 describe: func [x [integer!] y [integer!]] [
   switch true compose [
   (x = 1) [X is one]
   (y = 1) [Y is one]
   (x = 2) [X is two]
   (y = 2) [Y is two]
   (true)  [X and Y are too big!]
   ]
 ]
 
 ... (its also 10% faster, on my computer).
 

The timing comparison (even for the trival example I gave) is
*highly* dependent on the range of values which X and Y take!

The issue is that PIF will evaluate only enough guards to find the
first true one, while the SWITCH TRUE COMPOSE approach evaluates
*all* guards (and constructs a new block) every time.

If e.g. your timing test looks like

 t0: now/time/precise
 loop somebignumber [
 for x 1 hi 1 [
 for y 1 hi 1 [
 describe x y
 ]
 ]
 ]
 t1: now/time/precise
 print to-decimal t1 - t0

then using HI: 3 will give very different ratios between the two
approaches than HI: 6 or HI: 20 etc.

PIF allows the programmer easily to follow the standard heuristic of
making cheap (or high-probability) tests early to reduce the average
cost of a decision-driven expression, e.g.:

 dihedral-signum: func [
 x [number!]
 y [number!]
 z [number!]
 ][
 pif [
 x = 0 [0]
 y = 0 [0]
 z = 0 [0]
 10  square-root abs (
x * (x + 1) * y * (y + 1) * z * (z + 1) -
((x + 2) * (y + 3) * (z + 4))
 ) [1]
 true [-1]
 ]
 ]

Also, PIF allows the programmer to use failure of earlier tests as
guards for the evaluation of later tests, which is another useful
(and easy to read/write/understand) technique which the SWITCH TRUE
COMPOSE doesn't support:

 fuel-economy: func [
 fuel [number!]
 distance [number!]
 ][
 pif [
 fuel = 0 [No data]
 distance / fuel  20 [Poor fuel economy!]
 distance / fuel  40 [Great fuel economy!]
 true [Acceptable fuel economy]
 ]
 ]

In the above case, we can only reasonably make the later tests if
the test FUEL = 0 has failed.

In case anyone is tempted to redesign the tiny examples above, please
remember that those are off-the-cuff examples, and they aren't the
point!  The point is that there's inherent economy in only evaluating
enough expressions to get a result (instead of every possible one and
then picking the winner), and there are inherent safety and simplicity
considerations in knowing that a test can only be evaluated if the
previous ones have failed.

ON THE OTHER HAND ...

If I wanted to resurrect the discussion of a non-deterministic choice
among multiple options, I'd be very grateful that you provided a nice
way to express that!!!

 nif: func [[throw catch] b [block!] /local options] [
 options: copy []
 foreach [guard option] compose b [
 if guard [append options option]
 ]
 do random/only options
 ]

e.g. from among the guard/action pairs with true guard, evaluate an
arbitrarily-chosen action, so that

 nif [
 (x = y) [x]
 (y = x) [y]
 ]

nicely expresses that if X and Y are equal, then either one can be
used as the minimum of the two!

Thanks!

-jn-


-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Newbie Mailing List Questions

2003-12-18 Thread Joel Neely

Hi, Stan,

Welcome to the list!

Stan Silver wrote:
 Greetings,
 
 1.  Are mail list threads determined only by the subject?  In other words,
 can I add my two cents to an existing topic just by typing in the correct
 subject?  Or do I have to reply to an existing email?  Does Re: matter in
 the subject?
 

Take a look at the mail headers in your email client (e.g. in Netscape
or Mozilla there's an option in the View menu to do this).  If you
reply to a previous email, the mail client should include the email
ID of the onw you're replying to in the References header.  I think
that some email clients use this to construct the threading; If you
don't reply, but simply type the same string into the Subject then
it may not be picked up as belonging to the same thread.

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: a new switch-like flow-control function

2003-12-17 Thread Joel Neely

Hi, Anton,

Set the WayBack machine to 2000... ;-)

Anton Rolls wrote:
 I yearn (want), occasionally, a kind of any/switch-like
 flow-control function...

Some years ago we had a long discussion about generalizing IF on the
list, and kicked around various options/versions.  The copy I could
lay my hands on most quickly was Ladislav's refinement (the last in
the discussion???):

 pif: func [[throw catch] args [block!] /local res] [
 either unset? first res: do/next args [
 if not empty? args [
 throw  make error! [script no-arg pif condition]
 ]
 ][
 either first res [
 either block? first res: do/next second res [
 do first res
 ][
 throw make error! [
 script expect-arg pif block [block!]
 ]
 ]
 ][
 pif second do/next second res
 ]
 ]
 ]

PIF (Polymorphic IF) takes a block of guard-expression/block
pairs and uses the (first true) guard-expressions to select
block to be evaluated.  It can be used (I believe) essentially
as you were asking.

Refactoring PIF to iterative form is left as an exercise for
the reader!  ;-)  As long as the argument block isn't too long
the recursion likely won't be a problem.

Heres a sample usage:

 describe: func [x [integer!] y [integer!]] [
 pif [
 x = 1 [X is one]
 y = 1 [Y is one]
 x = 2 [X is two]
 y = 2 [Y is two]
 true  [X and Y are too big!]
 ]
 ]

which behaves as:

  describe 1 1
== X is one
  describe 2 1
== Y is one
  describe 2 2
== X is two
  describe 3 2
== Y is two
  describe 3 3
== X and Y are too big!

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Rebol API to DyBASE

2003-12-17 Thread Joel Neely

Hi, Konstantin,

Maybe even worse?

Konstantin Knizhnik wrote:
 
 And as far as Rebol hash is also series, appending element to it
  cause a lot of reallocations, so complexity of insert operation
  seems to be linear (instead of constant). And if we use insert
  hash instead of append hash (not insert tail hash), then
  performance becomes really awful - copying all series element
  increase complexity to quadratic and insertion of 10 integer
  elements in hash takes about half an hour (less then second in all
  other languages).
 

INSERTs into a fresh hash (created each time with MAKE HASH! []):
Appears to be increasing faster than quadratically!

# eltsseconds   ratio  quad  slowdown
 1  3.065
 2 25.8178.423   4   2.106
 3 63.682   20.777   9   2.309
 4123.417   40.267  16   2.517


APPENDs into a growing hash (not reconstructed between runs):

 # elts   seconds
  4 2.153
  4 6.69
  410.956
  415.453
  419.568

Here the number of appends in each stest is the same, but the time
complexity of managing a growing structure shows up; likewise, for
a simple block:

APPENDs into a growing block:

 # elts   seconds
  4 2.073
  4 6.529
  410.735
  414.962
  418.907

If we take out the reallocation-for-growth issues we get these:

APPENDs into a growing hash initialized with MAKE HASH! 20

 # elts   seconds
  4 0.22
  4 0.251
  4 0.2
  4 0.33
  4 0.281

APPENDs into a growing block initialized with MAKE BLOCK! 20

 # elts   seconds
  4 0.17
  4 0.17
  4 0.171
  4 0.191
  4 0.171

Preallocation of space (whenever possible ;-) is our friend!

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: What does REBOL fix?

2003-12-17 Thread Joel Neely

Hi, James,

Were you just joking?  (OBTW, REBOL isn't the only language
that supports dialects...)

James Marsden wrote:
 
 Dialecting in Rebol, more fun than Latin!

Damien Conway has actually written a Latin dialect for Perl!

[begin excerpt]

 Lingua::Romana::Perligata -- Perl for the XXI-imum Century
   Damian Conway
School of Computer Science and Software Engineering
 Monash University
  Clayton 3168, Australia

 Abstract

 This paper describes a Perl module -- Lingua::Romana::Perligata --
 that makes it possible to write Perl programs in Latin. A plausible
 rationale for wanting to do such a thing is provided, along with a
 comprehensive overview of the syntax and semantics of Latinized
 Perl. The paper also explains the special source filtering and
 parsing techniques required to efficiently interpret a programming
 language in which the syntax is (largely) non-positional.

...

 The Sieve of Eratosthenes is one of oldest well-known algorithms.
 As the better part of Roman culture was ``borrowed'' from the
 Greeks, it is perhaps fitting that the first ever Perligata
 program should be as well:

 #! /usr/local/bin/perl -w

 use Lingua::Romana::Perligata;

 maximum inquementum tum biguttam egresso scribe.
 meo maximo vestibulo perlegamentum da.
 da duo tum maximum conscribementa meis listis.

 dum listis decapitamentum damentum nexto
 fac sic
 nextum tum novumversum scribe egresso.
 lista sic hoc recidementum nextum cis vannementa da listis.
 cis.

 The use Lingua::Romana::Perligata statement causes the remainder
 of the program to be translated into the following Perl:

 print STDOUT 'maximum:';
 my $maxim = STDIN;
 my (@list) = (2..$maxim);

 while ($next = shift @list)
 {
 print STDOUT $next, \n;
 @list = grep {$_ % $next} @list;
 }

 Note in the very last Perligata statement (lista sic hoc...da
 listis) that the use of inflexion distinguishes the @list that
 is grep'ed (lista) from the @list that is assigned to (listis),
 even though each is at the ``wrong'' end of the statement,
 compared with the Perl version.

[end excerpt]

For those with a classical education (and a high tolerance for pain
;-) the full paper is available at

 http://www.csse.monash.edu.au/~damian/papers/HTML/Perligata.html

It's a hilarious tour-de-force!

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: What does REBOL fix?

2003-12-16 Thread Joel Neely

- REBOL: The message is the medium.

- REBOL: Programming for block heads

- REBOL: Life's too short to write long programs

- REBOL: Fight carpal tunnel syndrome!

- REBOL: Good things come in small packages

- REBOL: Because Von Neumann was right!

- Real Expressiveness Based On diaLects

- Radical Economy Built Of Literals

- REBOL: just DO %it

- Fewer moving parts - more parts move

- REBOL: Spread the WORD!

- REBOL: word up!

- REBOL: the last WORD in programming

- REBOL... I :it

- REBOL... :on-the-network

- foreach program your-to-do-list [:REBOL]

- REBOL: because this bumpersticker is too shor

 On 14-Dec-03, [EMAIL PROTECTED] wrote:
 
 
Can we find a snappy one-liner?
 
 
http://www.paulgraham.com/fix.html
 



-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: What does REBOL fix?

2003-12-16 Thread Joel Neely

Hi, Gabriele,

Gabriele Santilli wrote:
  Hi Jason,
 
  On Monday, December 15, 2003, 6:02:50 PM, you wrote:
 
  JC Yes but that is still also true for  HTML, XSLT, Perl, Python,
  JC PHP, Java, C,
  JC etc..
 
  How do you MOLD some PHP code and send it to another computer? ;-)
 

I disclaim all knowledge re PHP, but here's a trivial Perl client
to fetch and execute/evaluate source from a remote host.

   use LWP::Simple;
   eval get (http://your-site-here;);

The only point I was making in my earlier comment was that there
are several languages that are highly platform-neutral.  It's
also true that many of them are mobile in the sense of being
able to migrate run-ning/-nable code across the 'Net.

I guess one has to decide whether a one-line summary for REBOL (or
any other language) is to be:

a) a claim of a unique strength of the language (in contrast to
other languages of the claimant's in-depth knowledge),
b) a bullet point naming something the language does well (whether
or not other languages do so as well),
c) a bumper-sticker slogan intended primarily for fun (as in my
recent list of submissions), or
d) a sufficiently intriguing statement to motivate others to look
at the language.

And, of course, submitting types (b), (c), or (d), and having them
perceived as if of type (a) is the basis is the basis of many
language holy wars!  ;-)

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: What does REBOL fix?

2003-12-16 Thread Joel Neely

Hi, Maxim,

Maxim Olivier-Adlhoch wrote:
 
 ...  In this case, rebol outdoes everybody, IMHO.
 For security, you can just encrypt the data before sending it,
  and even that is (rather) easy to integrate right in a protocol.
 

That's not the only security issue.  Encrypting the source as it
moves over the wire doesn't protect one from bugs (or malicious
intent) in the code itself once executed.

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: What does REBOL fix?

2003-12-16 Thread Joel Neely

Hi, Ged,

Ged Byrne wrote:

   use LWP::Simple;
   eval get (http://your-site-here;);

 
 The code required to pass a string to another machine
 and have it execute is simple enough, but it isn't
 enough for the real world.
 
 The code as given presents a massive security risk. 
 

I completely agree.  I was only trying to show that the
classic REBOL example

do read http://your-site-here

isn't unique.


 So you have to construct sandboxes and all the rest of
 it.  Layers upon layers of complexity.
 

Which is as non-trivial in REBOL as in other languages.

 
 ...  On the other hand, the ability to send
 an expression for another machine to execute is
 central to Rebol's purpose.
 

But the ability to store/send an expression for later
evaluation (whether on the same machine or not!) is a part
of MANY current languages.


 I think I may be taking this all too seriously.
 

I think we all are!  ;-)

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: What does REBOL fix?

2003-12-15 Thread Joel Neely

Hi, Ged,

Ged Byrne wrote:
 
 Because every other language is trapped on just one computer.
 

Let's be fair.  There are MANY languages that are highly portable
in today's world: Perl, Python, Ruby, Java, and a whole slew of
open-source efforts.

And we're still waiting for the MacOS/X version of /View...

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] rot13

2003-12-14 Thread Joel Neely

First, thank you for the effort you've put into the ROT13 page
at:

 http://www.miranda.org/~jkominek/rot13/

With respect to your page on REBOL:

 http://www.miranda.org/~jkominek/rot13/rebol/rot13.r

and especially with respect to the Note to others...

I suggest that it is unfair to condemn a programming language on
the strength of an overly complicated, poorly-written function by
someone who is clearly unfamiliar with the language.  I can think
of several ways to write the rot13 conversion in a much more
natural-to-REBOL style.

The quickest (for me) to write uses REBOL's object mechanism, and
generates the translation table algorithmically at object set-up
time (as a one-shot initialization to reduce risk of typos):

rot13: make object! [
 xlate: make string! 78
 for ch #a #m 1 [append xlate reduce [ch  ch + 13  ch]]
 for ch #A #M 1 [append xlate reduce [ch  ch + 13  ch]]
 code: func [s [string!] /local result] [
 result: make string! length? s
 foreach ch s [
 insert tail result any [select/case xlate ch ch]
 ]
 result
 ]
]

It would be invoked on a string by evaluating

 rot13/code somestringexpression

and extending this to process an file (or standard input) is easy.

Again, thanks for the comparisons, and I hope to offer the above
comments in the spirit of assistance, not negativism!

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Guru's please help improve ROT13 algorithm !

2003-12-14 Thread Joel Neely

I submitted a cleaner one (than what's on the ROT13 page) along with
some remarks, and copied the list here, and then saw Sunanda's reply:

[EMAIL PROTECTED] wrote:
 
 http://www.rebol.org/cgi-bin/cgiwrap/rebol/view-script.r?script=rot-13.r
 

WRT that version, I'll add my $0.02...

rot-13: func [
 {Converts a string to or from Rot-13}
 data [any-string!]
 /local scrambled rot-chars rot-char
][
 rot-chars: 
{anabobcpcdqderefsfgtghuhivijwjkxklylmzmANABOBCPCDQDEREFSFGTGHUHIVIJWJKXKLYLMZM}
 scrambled: copy 
 foreach char data [
 if none? (rot-char: select/case rot-chars char) [rot-char: char]
 insert tail scrambled :rot-char
 ]
 return scrambled
]

My suggestions follow:

1) I prefer to avoid typo-prone strings when I can.
2) Both the above and my submission to the ROT13 site would benefit
from comments explaining the construction of the translation
string as related to SELECT/CASE.  It is a nice REBOL-ism that
we only need 39 characters per case as opposed to 52!
3) I'd rather initialize the result as an empty string with the full
(known) length preallocated to avoid excessive memory management
overhead for longer arguments.
4) The use of the get-word (:ROT-CHAR) is surprising (but marginally
defensible by speed?)
5) The if-none-then-use-default pattern is a great opportunity to use
another REBOL-ism, ANY.

I did a little benchmarking with four versions:

  code - is the version from my earlier post,

if/get - replaces the FOREACH body with

 if none? cc: select/case xlate ch [cc: ch]
 insert tail result :cc

 similar to the version in the script library

if - simply replaces the get-word (:CC) with the word itself

 if none? cc: select/case xlate ch [cc: ch]
 insert tail result cc

either - evaluates the replacement character as an expression
 as the last argument of the INSERT

 insert tail result
 either none? cc: select/case xlate ch [ch] [cc]

The results of a quick timing test (50,000 evaluations of each
function on a 243-character string) are

  rot13/time-it 5 datum
   code: 108.356
 if/get: 132.24
 if: 133.502
 either: 137.117

The use of the get-word saves about 1% to the run-time of the function
(if/get vs is).  The time for EITHER vs IF was a bit of a surprise to
me, because it added another 3-4% to the run time.

Comparing the object/method version vs a stand-alone function, we can
pull a REBOL-persistence-of-series trick:

rot13: func [s [string!] /local result xlate] [
 if empty? xlate:  [
 for ch #a #m 1 [append xlate reduce [ch  ch + 13  ch]]
 for ch #A #M 1 [append xlate reduce [ch  ch + 13  ch]]
 ]
 result: make string! length? s
 foreach ch s [
 insert tail result any [select/case xlate ch ch]
 ]
 result
]

(not that I'd ever write somehing like that, for several reasons ;-)
or embed the translation strings in place of the local XLATE, and get
the following timings:

  fn-vs-obj 5 datum
method: 108.255
  stateful: 107.405
 stateless: 107.514

where stateful is the above ROT13 function, and stateless uses the
literal instead of persistence.

Any critiques or suggestions for improvement to my object-based version
are welcome!

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: [tek@wiw.org: Re: rot13]

2003-12-14 Thread Joel Neely

Hi, Julian,

Julian Squires wrote:
 
 Hi.  I sent this reply off promptly, but I was unable to send to the
 rebol list without a subscription.

I'll be glad to forward it.

 I evaluated rebol again later,
 having learned more about similar languages, but I find ruby more
 suiting to my personal preferences.

Actually, I'm a bit of a polyglot myself (mostly Perl and Java for
work, still dabbling at Python, bought Dave  Andy's Ruby book but
haven't had time to invest in serious reading/playing.)  I get very
interested in seeing how mental models of various languages shape
(or at least influence) one's design and coding, and would likely
have spent more time on Python had it been around when I decided to
learn Perl.

 Cheers.  (hoping to never have to hear about this again, and hoping to
 meet people under friendlier circumstances than language wars.)
 

Happy holidays (and I'll try to point a cold fire-hose at some of
the flamers! ;-)

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] REBOL in another multi-language site...

2003-12-08 Thread Joel Neely

...by some guy with WAYYY too much computer access!  ;-)

http://www.kernelthread.com/hanoi/html/r.html

-- 
Joel Neelycom dot fedex at neely dot joel

I had proved the hypothesis with a lovely Gedankenexperiment,
but my brain was too small to contain it.  --  Language Hat




-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Some other questions

2003-11-23 Thread Joel Neely

Hi, Mike,

Here we jump off the deep end...  ;-)

Mike Loolard wrote:
 
 5) On the webpage about objects one passage mentioned that sub-objects
 don't get cloned-
 what does that mean ? Reading that I would expect that all objects within an
 object aren't
 available when I create an object on the basis of that object.
 But I seem to be able to use it anyway. Maybe I am getting something wrong
 here ?
 

If you have an object like this:

 proto: make object! [
 ID: 1
 label: My object
 ]

then whenever you say

 instance-1: make proto []

REBOL will implicitly clone/copy the string value for the LABEL
attribute, so that the new object doesn't have the *same* string
as the prototype.

Aside on Same-ness:

 Consider this transcript:

  a: Whoopee!
 == Whoopee!
  b: a
 == Whoopee!
  a/8: #?
 == Whoopee?
  b
 == Whoopee?

 The reason that the value for B changed is that B was set to (refer
 to) the *same* string as A (i.e. not a copy):

  a = b
 == true
  same? a b
 == true

 therefore there's only one string, but A and B can both get at it.
 On the other hand, if we explicitly ask for copying:

  a: Whoopee!
 == Whoopee!
  b: copy a
 == Whoopee!
  a = b
 == true
  same? a b
 == false
  a/8: #?
 == Whoopee?
  b
 == Whoopee!

 A similar situation (equal but not same) would result from saying

  a: Whoopee!
 == Whoopee!
  b: Whoopee!
 == Whoopee!

 It's important to remember that same and equal aren't the same!

End of Aside on Same-ness

That means that we can examine our objects:

  ? proto
 PROTO is an object of value:
 make object! [
 ID: 1
 label: My object
 ]
  ? instance-1
 INSTANCE-1 is an object of value:
 make object! [
 ID: 1
 label: My object
 ]
  same? proto/label instance-1/label
 == false

and see that the LABEL attributes are equal strings, but are not the
same string.

Now, suppose that our prototype had an object as the value of one of
its attributes instead:

 proto: make object! [
 ID: 1
 label: make object! [
 part-nr: 38562
 name:Flanged widget
 ]
 ]

and we used it as the basis of a new instance:

 instance-1: make proto []

Now we can examine our objects

  ? proto
 PROTO is an object of value:
 make object! [
 ID: 1
 label:
 make object! [
 part-nr: 38562
 name: Flanged widget
 ]
 ]
  ? instance-1
 INSTANCE-1 is an object of value:
 make object! [
 ID: 1
 label:
 make object! [
 part-nr: 38562
 name: Flanged widget
 ]
 ]
  same? proto/label instance-1/label
 == true

and see that the sub-object referred to be the LABEL attribute
of INSTANCE-1 is the *same* object that is referred to by the LABEL
attribute of PROTO.  That means (again) that changes/mutations of
that sub-object will be seen everywhere that it is referenced.

  replace proto/label/name widget blivet
 == Flanged blivet
  ? instance-1
 INSTANCE-1 is an object of value:
 make object! [
 ID: 1
 label:
 make object! [
 part-nr: 38562
 name: Flanged blivet
 ]
 ]

Now, to sum all of that up in a single sentence:

 When a new object is created from a prototype object,
 series-valued attributes of the prototype are copied,
 but object-valued attributes are shared.

Hope this helps!

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: what a subject ;-) Re: Re: [enum][constructor][memory][cloning][vid] Some other questions

2003-11-22 Thread Joel Neely

Hi, Petr,

Petr Krenzelok wrote:
 I am sorry, maybe I missed significant discussion to the topic, but 
 don't you guys find subject key-words a bit contraproductive?
 

I think the problem is not with key words, but with trying
to cram too many topics into a single email/thread.

 
 Use decent mailers as Mozilla and you will not have trouble searching 
 for certain topics ;-)
 

True.  However, there's more than searching involved here.
Subject keywords (when properly used) allow you to scan the
inbox to see which emails to read first, ignore, etc.

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] [email] Re: Some other questions

2003-11-22 Thread Joel Neely

Hi, Mike,

Mike Loolard wrote:
 I hope you guys don't mind me asking some other questions I have come up
 with meanwhile.
 

Welcome to the list!  I'm sure you'll find it as helpful and
friendly as I have.  However, let me suggest that it will
make discussions easier to follow if you will put each question
(or small group of closely related questions) in a separate
email.  That way people can follow -- and participate in the
discussions -- in a more focused way.

Happy REBOLing!

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: [array] Some other questions

2003-11-22 Thread Joel Neely

Hi, Andrew,

A J Martin wrote:
 Anton wrote:
 
Watch out though, each item in chickenfarm is the same chicken object:
 
 Yes! You've found a bug in 'array!
 

It's not a bug, since AFAIK there's no published specification
that says ARRAY should behave any differently than it does.
We've seen this issue before, in connection with other reference
types, as in

foo: Hi!
   == Hi!
gorp: array/initial 10 foo
   == [Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi!]
foo/2: #a
   == Ha!
gorp
   == [Ha! Ha! Ha! Ha! Ha! Ha! Ha! Ha! Ha! Ha!]

Given the available documentation for ARRAY:

? array
   USAGE:
   ARRAY size /initial value

   DESCRIPTION:
Makes and initializes a series of a given size.
ARRAY is a function value.

   ARGUMENTS:
size -- Size or block of sizes for each dimension
(Type: integer block)

   REFINEMENTS:
/initial -- Specify an initial value for all elements
value -- Initial value (Type: any)

it is consistent that the (single!) initial value is uses for all
elements.

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] [array] [syntax] Re: Some other questions

2003-11-22 Thread Joel Neely

Hi, Mike,

Anton has already given a direct answer, but let me dig deeper.

Mike Loolard wrote:
 
 1) If I have an object - how do I create an array of objects with it ?
 for example
 
 chicken: make object! [
 tasty: wings
 ]
 
 now I would want to have an array of objects of that type.
 
 I tried it like that:
 
 chickenfarm: make chicken [] array 10
 
 It doesn't seem to work that way, though ?
 

What you have written is two distinct expressions:

 chickenfarm: make chicken []

and

 array 10

One of the crucial light-bulbs that went on in my head when I
first began using REBOL is the following:

 REBOL has no syntax!

(other than the low-level lexical syntax for e.g. strings, numbers,
etc., but I keep the sentence short for emphasis and effect.)

All you have in REBOL is values, and when you put a bunch of them
together, you have expressions.  That's all.  So let's look at the
expressions you wrote, step by step.

 chickenfarm:; this is a set-word which will take the value
 ; of the immediatly-following expression
 make; use HELP; make wants a TYPE/SAMPLE and a SPEC
 chicken ; this is an object, so MAKE will create an object
 []  ; ... with this spec, i.e. with the same words
 ; as the original chicken with no added words
 ; or new values for the same words

At this point, make has a prototype object and an empty spec, so it
can construct a new object just like CHICKEN.  Then, at that point,
the expression following CHICKENFARM: has completed evaluation, so
CHICKENFARM is set to that result.  Now we continue:

 array   ; again, use HELP, to learn that ARRAY wants a
 10  ; size (but the initial value is optional).  So...

At this point, ARRAY has a size (but no initial value, as you didn't
use the /INITIAL refinement) and so happily creates a 10-element
block, with each element being NONE (REBOL's value that means nothing
here).

I hope I'm not insulting your intelligence with the details above!
Reading through your email, I get the feeling that you may still be
trying to read/write REBOL as if it were some other language, and
just want to suggest a shift in perspective that I found helpful
when I was beginning with REBOL.

-jn-






-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] [enum] Re: Some other questions

2003-11-22 Thread Joel Neely

Hi, again, Mike,

Mike Loolard wrote:
 
 2) How do you create custom types ?
 I am talking of a way to emulate the typedef behavour in C ?
 How would you go to create an enum type in REBOL ?
 

Strictly speaking, there are two answers to your first question:

1)  You can't.  But REBOL has a very rich set of types already,
 so you can often find a type that suits your purpose (if you
 ask yourself the right questions!)

2)  You can create objects, and use those as prototypes to creat
 other objects.

There's a real problem is with your second question (and if you
don't read anything else I write, PLEASE remember this one!)

 COBOL is alphabet blocks.
 C is a set of tinkertoys.
 Java is an Erector Set (IIRC similar to Meccano in Europe?)
 with all kinds of braces, motors, girders, nuts, and bolts.
 Perl is a Swiss-army chainsaw.
 REBOL is modeling clay.

 Learn to use each one according to its own nature.

Let's talk about question 3 and then return to the first one.  As
I said above, we must first ask ourselves the right questionS.  If
your question is really

 How can I create a set of names for distinct, related values
 to use in my REBOL program?

Then the answer is easy: words!

Suppose I am doing something with personnel data, and want to
represent the status of each employee.  I could do something like
the following:

 employee: make object! [
 ID: 0
 name:   
 hire:   now/date
 status: 'full-time
 ]

Notice that the STATUS attribute is a word! value, whose name is
chosen for mnemonic value.  That's all there is to it.  Now let's
proceed to hire some people, with:


 bob: make employee [
 ID: 1234
 name:   Robert R. Robertson
 hire:   01-Jan-1997
 ]

 carol: make employee [
 ID: 2345
 name:   Carolyn C. Carroll
 hire:   14-Feb-1998
 ]

 ted: make employee [
 ID: 3456
 name:   Theodore T. Theoden
 hire:   27-Nov-1999
 status: 'part-time
 ]

 alice: make employee [
 ID: 4567
 name:   Alicia A. Allison
 hire:   31-Dec-2000
 status: 'leave
 ]

Notice that BOB and CAROL are created with the default status of
full time, while TED and ALICE each have different status.  Here
we had to quote the words, making them LIT-WORD! values, to keep
REBOL from trying to evaluate them.  We don't care about whether
there's a value associate with e.g. LEAVE , but simply want to use
the word itself as a label.

Let's use a block as our pretend database:

 all-employees: reduce [bob carol ted alice]

The reason we had to REDUCE that block is that here we don't want a
block of words, but want a block containing the objects that those
words are set to.  (We could also have written a constructor
function which would make a new employee from the arguments passed
to it, and would append that new employee to ALL-EMPLOYEES at the
same time.)

Then we can produce an employee report, grouped by status with the
following (rather inefficient!) function:

 group-report: func [
 /local count
 ][
 foreach [
 status title
 ][
 full-time  Full Time (at least 35 hrs/wk)
 part-time  Part Time (up to 34 hrs/wk)
 leave  Leave of Absence (half benefits)
 suspended  Disciplinary Suspension (no benefits)
 terminated Not Here (no further information available)
 ][
 count: 0
 print [title newline]
 foreach emp all-employees [
 if emp/status = status [
 print [tab emp/hire tab emp/ID tab emp/name]
 count: count + 1
 ]
 ]
 print [newline count employees in this status newline]
 ]
 ]

When we evaluate that function, we get:

  group-report
 Full Time (at least 35 hrs/wk)

  1-Jan-1997  1234Robert R. Robertson
  14-Feb-1998 2345Carolyn C. Carroll

 2 employees in this status

 Part Time (up to 34 hrs/wk)

  27-Nov-1999 3456Theodore T. Theoden

 1 employees in this status

 Leave of Absence (half benefits)

  31-Dec-2000 4567Alicia A. Allison

 1 employees in this status

 Disciplinary Suspension (no benefits)


 0 employees in this status

 Not Here (no further information available)


 0 employees in this status

Notice that the second argument to the outer FOREACH in the function
above is a block containing alternating WORD! and STRING! values:  the
word is the name/symbol of a status, and the string is the associated
description.  (In a real application, this would be global to the
entire application, of course!)  Since we didn't REDUCE that block,
we literally have words and strings.

The REBOL word type can be used in this way -- 

[REBOL] Re: [array] Some other questions

2003-11-22 Thread Joel Neely

Hi, Andrew,

A J Martin wrote:
 Hi, Joel!
 
/initial -- Specify an initial value for all elements
it is consistent that the (single!) initial value is uses for all
 elements.
 
 Hmmm, at the moment, I can't see a good use for an array that has multiple
 references to the one series or object. :-/ The /Initial refinement seems,
 to me, to indicate a initial value for each element, implying that each
 element in the result is distinct.

I guess we're just differing over the interpretation of the words
here.  I read the phrases a value for all elements and a value
for each element as slightly different (but see below).

  I believe that 'array is more useful to
 most people when each value is a unique value, like:
 

When dealing with reference values I certainly agree that it would
be more useful if /INITIAL gave a *spec* to be used to construct
an initial value for each element.  My quibble was only with the
notion of calling the present behavior a bug, instead of saying
that it would have been more useful if ARRAY worked in the way that
you (and I) would have expected.

I'm just being an old grouch on this point because I've recently
been bitten again by a subtlety that isn't documented anywhere
that I could find, so I had to resort to particle physics just
to figure out what the interpreter was doing (and have to hope
that it won't change in a future release).

It's just my old build-to-spec temperament, chanting:

 If there ain't no spec,
 there ain't no bugs!

;-)

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] [datatypes] action! vs. native! vs function!

2003-11-22 Thread Joel Neely

Hi, all,

OK, so a FUNCTION! is a function written in REBOL itself (what
FORTH used to call high-level in contrast with primitive).

I've always thought of NATIVE! as primitive in the above
contrast -- a function written inside the interpreter in C
(or whatever), but then ACTION! enters the picture and leaves
me scratching my head.

Does anyone know the difference between NATIVE! and ACTION!
types?

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] [constructors] Re: Some other questions

2003-11-22 Thread Joel Neely

Hi, Mike,

Mike Loolard wrote:
 
 3) Back on objects:
 objects seem to be pretty neat in REBOL - but I didn't find anything about
 implementing
 and using constructor/destructors ?
 
 I know I could manually add a function that serves as constructor each time
 I create an object, but is that the way REBOL requires it ?
 

You don't need constructors in REBOL.  Since REBOL also doesn't have
classes, objects can either be created directly:

 tally: make object! [
 count: 0
 total: 0
 put: func [x [number!]] [
 total: total + x
 count: count + 1
 ]
 get: func [] [
 reduce [total total / max count 1]
 ]
 reset: func [] [count: total: 0]
 ]

or created from a prototype object.  In this second case, you must
supply a block (possibly empty) of changes or additions.  The simplest
case is constructing another object with identical properties:

 tally2: make tally []

whose initial values will be based on the current values of the object
used as a prototype.

You can also base a new object on an existing one, but make some changes
in the initial state, add methods/attributes, or change methods.

 enr0n: make tally [
 total: 100
 put: func [x [number!]] [
 total: total + x + 100
 count: count + 17
 ]
 ]

If you *want* to implement a function that serves as a constructor, you
certainly can, using the above standard capabilities.  As OBJECT! is a
first-class data type in REBOL, there's nothing magical about writing a
function which returns an object:

 make-tally: func [] [
 make object! [
 count: 0
 total: 0
 put: func [x [number!]] [
 total: total + x
 count: count + 1
 ]
 get: func [] [
 reduce [total total / max count 1]
 ]
 reset: func [] [count: total: 0]
 ]
 ]

...but that doesn't buy us much.  It would be more useful if we had a
small number of attributes that were initialized based on the function's
arguments, but that's just a convenience issue, not a fundamental issue
of REBOL capabilities.

Finally, when I know I will be using multiple similar objects, I have
sometimes put a function within the object itself to provide me with
another, similar object (again just for convenience), as in:

 tally: make object! [
 count: 0
 total: 0
 put: func [x [number!]] [
 total: total + x
 count: count + 1
 ]
 get: func [] [
 reduce [total total / max count 1]
 ]
 reset: func [] [count: total: 0]
 new: func [/local result] [
 result: make self []
 result/reset
 result
 ]
 ]

That way the fresh instance is always initialized to some standard
beginning state.  Actually, I'd be more likely to write this as:

 tally: make object! [
 count: 0
 total: 0
 put: func [x [number!]] [
 total: total + x
 count: count + 1
 ]
 get: func [] [
 reduce [total total / max count 1]
 ]
 reset: func [] [count: total: 0  self]
 new: func [] [do in make self [] 'reset]
 ]

As for destructors, there's little need in REBOL as memory management
(including garbage collecting) is automatic.  If you *want* to add a
method to an object to release big data structures, print final state,
or whatever, you can certainly do so, but you'll have to invoke it for
yourself, as the concept of an automatic call to a finalizer is not
in REBOL.

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Some other questions

2003-11-22 Thread Joel Neely

Hi, Mike,

Mike Loolard wrote:
 
 4) In the same context:
 how do I actually 'free' memory/variables ?
 

You don't need to do so, as memory management in REBOL is automatic
(including collection of circular garbage).  However, if you are
doing some processing of large structures, you can limit the need
for REBOL to go back to the O/S and ask for more memory by clearing
out stuff you no longer need.  If you only have one word that refers
e.g. to a large block, you can simply set that word to a trivial value,
such as NONE, to make the previous contents available for garbage
collection.

 blort: make block! 10
 repeat i 10 [append blort sine i]  ; whatever
 ; then, after that block is no longer needed...
 blort: none

You can also use CLEAR to remove all values from a series (from the
current position).  This can be handy if you want to reuse the space
after the initial contents are no longer needed.

 blort: make block! 10
 repeat i 10 [append blort sine i]
 ; do something with sines
 clear blort
 repeat i 10 [append blort cosine i]
 ; do something with cosines
 clear blort
 repeat i 10 [append blort tangent i]
 ; do something with tangents
 ;... etc.

But, again, unless you're working on huge structures, have a long-
lived process, and are running on a small-memory or slow box, there's
seldom any reason to worry about such things.

-jn-


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: [data structures] (was Re: [append][series]Appending to a series of strings)

2003-11-21 Thread Joel Neely

Hi, Ladislav, et al,

Ladislav Mecir wrote:
 Joel Neely napsal(a):
 
 REBOL seems to occupy a middle-ground position on this issue; it
  does not require you to declare the existence of a data structure
  (as e.g. Java does) but it *does* require that you allocate and
  initialize it explicitly.
 
 I think, that you are describing *only* a top-down approach here.
  A bottom-up approach might lead to:
 

No, not the way I understand those terms (top-down = beginning with
the overall top goal and working down to successively finder-
grained detail; bottom-up = beginning with detailed bottom concepts
and aggregating/building them up to the final goal).

Those terms have to do with *when* in the development process we
address a given level of detail; what I'm trying to focus on is the
issue of *whether* certain levels of detail have to be addressed at
all (regardless of when).

 get-value: function [
 ...
 ]
 
 set-value: func [
 ...
 ]
 
 inc: func [
 ...
 ]
 ... 
 
 In Rebol you can teach the language to do what you want it to,
  because Rebol facilitates the process of the language extension.
 

While I would probably write such things as methods on an object,
presenting those capabilities as three individual functions is
certainly a way to get the job done.  But in either case, whether
we sweep those details under an object or into separate functions,
the fact remains that -- at some point in our design and development
process -- we had to pick up the broom!

 
 ...   Finally, (back to the original discussion) Perl will even
automatically figure out when to allocate/initialize structures and
elements for me.
 
 
 What if you needed a different default value, wouldn't that leave
  you on your own in Perl?
 

Certainly, although the default applied in a given case depends on
the operation being performed: zero for numerical operations and
the empty string  for string operations.  And overriding those
defaults is easy; if we wanted to accumulate products of values
associated with keys (instead of sums) the key expressions would be:

 if (defined $tallies [$key]) {
 $tallies [$key] *= $val;
 } else {
 $tallies [$key] = $val;
 }

or

 $tallies [$key] = 1 unless defined $tallies [$key];
 $tallies [$key] *= $val;

And note, in passing, that the test to see whether a given element
of the data structure is defined is independent of what types of
data might be stored there.  The corresponding test in your GET-VALUE
was equivalent to:

 value: pick array index + 1
 either value [value] [0]

which would have to be re-engineered if we wanted e.g. an array which
might include LOGIC! or NONE! values.  (The fact that we even have to
think of such details is again my real point here.)

 
 I think, that the effect on thinking in Rebol may be caused more
  by inertia than by language limitations.
 

I'm not condemning REBOL for limitations, but merely observing that
different language designs reflect the designers' philosophies of
programming and choices about what would be most likely needed by the
programmer.  And I could certainly give examples of nice REBOL features
of REBOL that aren't built into Perl (see footnote).

I'd certainly agree that inertia in the sense that one tends to
think in habitual ways is a factor in almost everything we humans
do.  But please reread my statement before taking issue with it:

 As a polyglot, I'm less interested in picking sides in a
 political debate than understanding deeply the effects on
 my own thinking when I begin to think like a native in
 one or more of them.

As one begins to think like a native in language X, that means
that one has begun to overcome the pre-X habits, IMHO.  I'm not
going to lay any claim to REBOL-guru-hood, but I do believe my
approach to writing-in/thinking-with REBOL is different than when
I began using it some years ago.

I recently spent some time with a decades-old book of programming
puzzles of the recreational mathematics flavor.  I used REBOL to
construct my solutions, then compared my approach with the code in
the back of the book (given in C, BASIC, and Pascal).

I was repeatedly struck by the differences in my designs and those
of the book -- to the point that it was very difficult to compare
some of them in any meaningful way (although REBOL on my 600 MHz
laptop handily outperformed the timings in the book for compiled
C on an 8MHz Pc! ;-)

I often used recursive functions and/or dynamically-managed blocks
in my solutions; needless to say, both of these were absent from the
book.  But my interest goes even deeper than language features.  In
at least one puzzle, I had a single loop that operated on a small
number of variables holding only integer values.  But the thought
process by which I arrived at that solution was radically different
than that taken in the book's solution.

To whatever degree my design approach was an improvement over the
book's (and over my

[REBOL] Re: FW: Re: [append][series]Appending to a series of strings

2003-11-20 Thread Joel Neely

Hi, Ladislav,

Actually, it's not faster (for sufficiently large cases).  See below.

Ladislav Mecir wrote:
 Hi, my solution using Parse (I think, that it is much faster, than
  other solutions):
 

I did a bit of benchmarking with functions that use each of the three
strategies to generate a block of answers (value/count pairs).  I'll
include those functions at the end, in case anyone wants to verify
that I didn't mangle any code.

Using a SCORES block of random numbers between 0 and 100 (inclusive),
the iterative version scales up better than the parse-based version
as the size of the SCORES block increases (all times in seconds):

 sizeiterative  remove-each  parse-based
  10001E-20.28 0
 1   0.3512.8740.24
10   3.024   36.8134.637
20   4.787   --4.556
30   6.74--6.94
40   8.832   --   14.371
50  11.887   --   18.517
   100  21.891   --   39.227

I gave up VERY quickly on the remove-each-based version; it gets
eaten alive by memory management overhead.

Since the parse-based version sorts (a copy of) the scores block,
its time complexity must be at least O (n log n).

The iterative version is only O (n), so it will be faster for 
sufficiently large n.

I should also point out that the iterative version requires only
one value at a time; it can work on an arbitrarily large set of
values (e.g., being retrieved across a network connection, read
from a huge data file, resulting from computation in a loop, etc.),
but the remove- and  parse-based versions require the entire set
to be available for sorting.

There's one final point, but I'll post it separately.

-jn-

Ladislav Mecir wrote:
scores: clear []
loop 30 [append scores random 20]
group: [p: set i integer! any i q: (print [score: i tallies: 
 offset? p q])]
parse probe sort scores [any group]
 
-Original Message-
From: Anton Rolls [mailto:[EMAIL PROTECTED]

; initialize some random scores
scores: clear []
loop 30 [append scores random 20]

; figure out how many of each score
tallies: clear []
foreach uscore sort unique scores [
  append/only tallies reduce [
   uscore
   length? remove-each score copy scores [uscore  score]
   ]
]


SOURCE CODE FOR TIMED FUNCTIONS IS GIVEN BELOW:

;iterative version

 tally-i: func [
 scores [block!]
 /local tallies result
 ][
 tallies: copy []
 foreach score scores [
 either found? here: select tallies score [
 here/1: here/1 + 1
 ][
 insert tail tallies reduce [score copy [1]]
 ]
 ]
 result: make block! length? tallies
 foreach [score tally] sort/skip tallies 2 [
 insert tail result score
 insert tail result tally
 ]
 result
 ]

;remove-each-based version

 tally-r: func [
 scores [block!]
 /local tallies
 ][
 tallies: clear []
 foreach uscore sort unique scores [
append/only tallies reduce [
 uscore
 length? remove-each score copy scores [uscore  score]
 ]
 ]
 ]

;parse-based version

 tally-p: func [
 scores [block!]
 /local group p q result
 ][
 result: copy []
 group: [
 p: set i integer! any i q: (
 insert tail result i
 insert tail result offset? p q
 )
 ]
 parse sort copy scores [any group]
 result
 ]


-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] [data structures] (was Re: [append][series]Appending to a series of strings)

2003-11-20 Thread Joel Neely

Hi again, Ladislav and all

Joel Neely wrote:
 Hi, Ladislav,
 
 I did a bit of benchmarking with functions that use each of the three
 strategies ...
 
 There's one final point, but I'll post it separately.
 

This has been very interesting, and your parse-based solution is an
*excellent* illustration of thinking with series-level operations
instead of element-level operations -- a classic bit of REBOL-style
thinking IMHO.

Perhaps I should blame my illustration that started this -- or how I
explained my request for alternative solutions -- because I was trying
to focus on a different issue than histograms!  (although it DID have
to do with language thinking styles ;-)

The design of every language with which I'm familiar reflects at least
two issues:  the conceptual model used by the designer(s)  (or lack
thereof!) and the decisions about what things to make easy for the
programmer using the language.

Both Perl and REBOL make it easy to use a variable -- you just start
using it and the language keeps up with what you're doing; no advance
declaration is required.  OTOH Java makes it easy to detect errors in
type mismatch as early as possible (at compile time), which REBOL and
Perl can't catch until the program is running.

Perl goes further and makes it easy to use data structures; if you try
to modify/store data, the appropriate place is automagically created
(and initialized to an appropriate value, depending on the operation
you are performing).  The Perl expression

 ++$array[$n]

means add one to the nth element of array. If the array doesn't have
n elements (or if the array doesn't even exist!), Perl will allocate
that position and and initialize it to zero before evaluating your
expression.

REBOL seems to occupy a middle-ground position on this issue; it does
not require you to declare the existence of a data structure (as e.g.
Java does) but it *does* require that you allocate and initialize it
explicitly.  REBOL certainly has some nice built-in facilities for
processing series data, but once you leave those you are *really* on
your own.  My original dinky demo was intended to compare that one
expression above with

  insert/dup tail tallies 0 score + 1 - length? tallies
  change at tallies score + 1 1 + pick tallies score + 1

or

  either found? here: select tallies score [
  here/1: here/1 + 1
  ][
  append tallies reduce [score copy [1]]
  ]

which are the equivalent in REBOL (given that it's the programmer's
responsibility to allocate and initialize the tally structure).

Of course, I'm well aware that I could initialize the tally structure
for e.g. all key values between 0 and 100 as a way to avoid the
dynamic initialization issues above...  (But my experience tells me that
as soon as I do that, some teacher will add an extra credit problem so
that some students can score 110! ;-)

Language design decisions have far-reaching (and often subliminal)
effects on the subsequent design thinking of programmers using the
language(s) in question.  One such issue that I find interesting is
the question of when I -- as the programmer -- must commit to a
decision regarding the data structures used within my programs.

COBOL and Pascal require that I commit to the type and size of every
array before submitting my programs to the compiler, and initialize
the structures appropriately (at run time, but before any other use).
Java requires me to commit to the type of an array, but lets me defer
the size committment until run-time when I actually initialize it.
Newer versions of Java provide the Vector class, which can be thought
of as an array that can change size during use.  Perl and REBOL (and
Python, et cetera) arrays/blocks not only let me dynamically resize
during use, I don't even have to commit to a single type of data to
put there!  Finally, (back to the original discussion) Perl will even
automatically figure out when to allocate/initialize structures and
elements for me.

Advocates of each of these languages will offer passionate arguments
for why the binding-time choices of their preferred language are good.
As a polyglot, I'm less interested in picking sides in a political
debate than understanding deeply the effects on my own thinking when
I begin to think like a native in one or more of them.

-jn-




-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: [data structures]

2003-11-20 Thread Joel Neely

Hi, Gregg,

Gregg Irwin wrote:
 
 ... For example, how would
 we build constructs in REBOL to emulate what Perl does with
 auto-sizing arrays,

Exactly what I was hoping for.  As an example, I've been using the
nested-block trick to simulate mutable arrays in REBOL for some time,
and have no specific problem/complaint with it (other than the fact
that it looks a bit funny... ;-)  However, I was hoping for some
additional suggestions from the list.

  or what would a Perlite/Perler/Perl-monger (proper
 term?) do to provide protection *against* auto-sizing if it wasn't
 desired.

I can think of three alternatives right off:

 ++$array[$n] if $minOK = $n  $n = $maxOK;

to ignore OOBVs (out-of-bounds values),

 ++$array[$n  $minOK ? $minOK : $maxOK  $n ? $maxOK : $n];

to force OOBVs to the violated boundary, or

 ++$array[$minOK = $n  $n = $maxOK ? $n : $default];

to force OOBVs to some default bucket.  The last two index expressions
(for those not familiar with C or Perl) are essentially equivalent to
the REBOL expressions

 either n  minOK [minOK] [either maxOK  n [maxOK] [n]]

and

 either all [minOK = n  n = maxOK] [n] [default]

I'd actually write the first of these in REBOL as

 max minOK min maxOK n

To say that in Perl one would need to define the min and max functions,
as they aren't built in.

-jn-




-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: [append][series]Appending to a series of strings

2003-11-18 Thread Joel Neely

Hi Seth,

See below...

Seth wrote:
   a: [1 2 3 4 5]
 == [1 2 3 4 5]
   b: []
 == []
   x: index? a
 == 1
   append b/:x hi
 == hi

At this point, take a look at the value of B to see why:

  b
== [hi]
  fourth b
** Script Error: Out of range or past end
** Near: fourth b
 
  b/:x
== none
 

   x: index? find a 4
 == 4

At this point B has no fourth element (ergo B/:X returns NONE) so...

   append b/:x hi
 ** Script Error: append expected series argument of type: series port
 ** Near: append b/:x hi
 
 In theory, shouldn't append do it's thing on b/4 ... What's with the 
 error? :\
 

...you can't treat that (non-existent) element as a series.

Unlike Perl, which automatically allocates and meaningfully initializes
previously non-existent data, REBOL requires that a value exist and be
of the correct type for whatever operation you attempt to perform on it.

-jn-




-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: [append][series]Appending to a series of strings

2003-11-18 Thread Joel Neely

Hi, Seth,

Seth wrote:
 Joel Neely wrote:
...you can't treat that (non-existent) element as a series.

Unlike Perl, which automatically allocates and meaningfully initializes
previously non-existent data, REBOL requires that a value exist and be
of the correct type for whatever operation you attempt to perform on it.
 
 Thanks everyone... I was coming from a Perl point of view here -- The 
 REBOL way is a lot more logical -- This is what I get for coding at 
 ungodly hours in the morning ;] Thanks... :D
 

IMHO neither more nor less logical, just differently logical.

Suppose one has a collection of small natural numbers (such as
test scores ranging from 0 to 100) and one wants to know how many
occurrences of each distinct number there are.

Using Perl arrays:

 # assume @scores contains the raw data with dups
 @tallies = ();
 foreach $score (@scores) {
 ++$tallies[$score];
 }
 foreach $score (0..$#tallies) {
 print $score: $tallies[$score]\n if $tallies[$score];
 }

Using REBOL blocks:

 ; assume SCORES contains the raw data with dups
 tallies: []
 foreach score scores [
 insert/dup tail tallies 0 score + 1 - length? tallies
 change at tallies score + 1 1 + pick tallies score + 1
 ]
 forall tallies [
 if 0  tallies/1 [print [-1 + index? tallies : tallies/1]]
 ]

or

 ; assume SCORES contains the raw data with dups
 tallies: []
 foreach score scores [
 either found? here: select tallies score [
 here/1: here/1 + 1
 ][
 append tallies reduce [score copy [1]]
 ]
 ]
 foreach [score tally] sort/skip tallies 2 [
 print [score ; tally/1]
 ]

REBOL is much more literal; there are no values that one does not
explicitly create (although it is possible to be implicitly explicit
at times ;-).  On the other hand, it is necessary explicitly to
manage details that aren't at the same logical level as the original
problem (making sure that there enough places to store the next
tally needed, etc).

I'd be interested in any *self-contained* solutions to the above task
that might be clearer than the above.

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] REBOLforces site down?

2003-11-17 Thread Joel Neely

I'm experiencing breakage with some links on www.rebolforces.com,
including the email link at the bottom of the front page.  Is that
site out of service, or are there just some glitches?

-jn-




-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: RSA Encryption

2003-11-13 Thread Joel Neely

Hi, Matt,

I'll give it a shot...

Matt MacDonald wrote:

Can someone please explain to me, in as few mathematical equations as 
possible, why RSA public/private encryption works?  ...  How is this 
any different from using a syncronous encryption method and then just 
sending the encryption key along with the data?  It just doesn't make sense to me.


Let's sneak up on it.  For simplicity of examples, suppose that
all of my messages will be made up of ONLY uppercase letters,
spaces, periods, or question marks (29 possible characters).
We can represent our characters via:

0 = space, 1-26 = A-Z, 27 = period, 28 = question mark

and then encode messages by doing arithmetic on the numbers (
as long as our results are limited to the range 0-28).

A trivial example would encode by adding some fixed value (mod
29) to the plaintext and decode by subtracting that same fixed
value (mod 29) to the plain text.  Here the here the algorithms
for encoding and decoding are different, but the keys for those
operations are the same.  Let's make the algorithm the same (by
adding the key mod 29 to each value), which means that the
decoding key is must be the mod-29 complement of the encoding
key.  IOW, if I encode by adding 3, I decode by adding 26.

In that simple case it is trivial to figure out the decoding key
from the encoding key.

Suppose I multiply by the encoding key (mod 29) instead.  It's
a bit more work, but still easy to figure out what decoding key
I can multiply by (mod 29) to get back the original character.

Suppose I use two encoding keys (a and b) and encode a character
by evaluating

encoded-character: a * plain-character + b // 29

Now it's slightly more complicated (or just plain time consuming)
to figure out what values of (c and d) will give me

plain-character: c * encoded-character + d // 29

i.e. the original character's number.

Enough dinky examples.  As we increase the mathematical complexity
of the formula, we discover that that the effort to find the
decoding key *EVEN IF WE KNOW THE ENCODING KEY AND THE FORMULA*
can increase substantially.

Public key cryptography is based on using certain mathematical
operations that *NOBODY* knows how to invert in reasonable time.

(Of course, that could change dramatically if quantum computing
provides us a way to factor arbitrary huge numbers quickly!)

Anyway, that's the core idea of why the public key can be made
... well ... public! without exposing the message content.

HTH!

-jn-




-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Another coffee break problem?

2003-11-11 Thread Joel Neely

Hi, Gregg,

Gregg Irwin wrote:
 
 JN The following 3-by-3 display is a simple magic square:
 
 JN  0  8  4
 JN  5  1  6
 JN  7  3  2
 
 JN because each row and each column sums to 12...
 
 No diagonals? I thought magic squares had to work on the diagonal as
 well? (not to be nit-picky or anything :)
 

To be equally picky ;-)

That's why I said simple magic square instead of totally magic.  I
was going to post a follow-up problem to refine the first program so
that it also checks diagonals.

Also, not all sources I've looked at insist on diagonal operations.  One
interesting way to generalize the problem is to magic rectangles with
different height and width.  In that case, the definition of diagonal 
becomes more interesting...

-jn-



-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Another coffee break problem?

2003-11-11 Thread Joel Neely

Hi, Anton...

Anton Rolls wrote:

 I can see you are going to ask us to
 generalize it later so it can do integers
 higher than 8.
 

Since Gregg has already partially debagged the cat, I'll admit that
I have some generalizations in mind, but not that particular one ;-)

 
 I think for this set of numbers 12 is the
 only sum you will get, but just to be clear,
 shouldn't it be: it's a magic square because
 each row and column sum to the same number ?
 

Yes, but only because a square is a rectangle with the same height
and width...

WARNING: YOU ARE NOW ENTERING THE [scary music] ALGEBRA ZONE!

A rectangular display of numbers with R rows and C columns contains
R*C cells.  The simplest way to fill those cells with distinct values
is to use the first R*C natural numbers, such that 0 = n  R*C.  The
sum of all of the values is then

 (+i : 0 = i  R*C : i) = R*C * (R*C - 1) / 2

Adding the requirement that all row totals be equal tells us that the
row total must be the grand total divided by the number of rows, so

 all row totals = R * C * (R * C - 1) / 2 / R
= C * (R * C - 1) / 2

and likewise

 all col totals = R * C * (R * C - 1) / 2 / C
= R * (R * C - 1) / 2

so that e.g. for a 3 x 5 simple magic rectangle,

 grand total= 3 * 5 * (3 * 5 - 1) / 2
= 15 * 14 / 2
= 15 * 7
= 105

 all row totals = 105 / 3 = 35

 all col totals = 105 / 5 = 21

and, of course, if R and C are equal, the magic row and col totals
will be equal (so e.g. for the 3 x 3 case, 9 * 8 / 2 / 3 = 12).

If I wanted to be sneaky, I'd ask how many magic rectangles there are
with 99 rows and 100 columns!

YOU ARE NOW ENTERING AN ALGEBRA-FREE ZONE!  ;-)


HINT AHEAD -- Don't read if you want to solve it on your own steam!

.
.
.
.
.
.
.
.
.
.

Since there are 362880 ways to arrange 9 distinct values, the key
issue is to do something more economical than simply generating all
possible permutations, checking each one for magicness.

-jn-



-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Curiosity

2003-11-11 Thread Joel Neely

Hi, Carlos,

For educational purposes (and just for fun... ;-) I'm currently
using REBOL on all of the following platforms:

Mac OS/X, Linux, W2000, WXP, W98, Solaris

I might add that I am only using /Core features.  One of the main
reasons I began using REBOL (the same is true of Perl, Python, ...
in short, all of my tools of choice) is the cross-platform support.

Until View is available for OS/X, I will not use it.

-jn-

Carlos Lorenz wrote:

 Hi list,
 
 I am very curious about to know
 how many of us use REBOL under Linux
 and how many use REBOL under Windows
 both at work and at home.
 Would you mind answer a this?
 Thanks
 Carlos
 



-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Opening Specific Ports

2003-11-11 Thread Joel Neely

Hi, Matt,

I claim no guruhood re networking, but...

IIRC, firewall rules can take both origin and destination ports into
account.  Could they use a rule that allows any client-side port, as
long as it is attempting to connect to a specified server/port where
the authorized service is available?

-jn-

Matt MacDonald wrote:
 
 I'm making a client software for other users.  I need to somehow limit the 
 ports that rebol will try to open on their computers so that their company 
 firewalls can be configured to allow access over those ports.  Or am I going 
 about it the wrong way?  Any networking gurus out there?
 

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Looking over the horizon - Rebol 3

2003-11-10 Thread Joel Neely

Hi, Andrew,

Thanks for starting what I hope will be a productive thread!  Now,
speaking strictly for myself, little of my REBOL wish list is about
adding features to the language.

Andrew Martin wrote:
 
 * Lots more datatypes! For example, a Telephone! data type, temperature,
 audio/sound data-type, metric and imperial units like 123.5Km, 50MpH,
 and so on...
 

No.  Please, no.  Please, please, no.

There have been plenty of threads in the past about the confusing and
not-completely-documented behavior associated with the existing plethora
of types.  Do we really want that situation compounded???  (e.g. what
happens when I add 2 to 123.5Km, what happens when I multiply 50MpH by
32F, ...)

I realy have only two wishes in regard to data types:

1)  Fully document the existing ones.
2)  Add support for promoting objects to true user-defined types.

I hope the first is obvious (and non-controversial) to the list.

Let me give a trivial example of the second issue, and then apply it
(in a non-trivial way, I hope! ;-) to your wish list above.

REBOL has a PAIR! type which can be used for 2D points, but suppose I
am working on projective geometry in a serious way.  I can define

 ; projective point

 ppoint: make object! [
 u: v: w: 0   ; projective coordinates of pline
 to-string: func [] [...] ; create a printable representation
 ...  ; other natural behavior of a ppoint
 ]

 ; projective line

 pline : make object! [
 p: q: r: 0   ; projective coordinates of pline
 to-string: func [] [...] ; create a printable representation
 ...  ; other natural behavior of a pline
 ]

after which I can sprinkle such things as the following thru my code:

 P1: make ppoint [u: -1  v:  2  w:  1]
 P2: make ppoint [u:  4  v:  5  w: -1]
 L1: make pline  [p:  1  q: -1  r:  0]

but the list of useful things I *can't* do includes the following:

 ; function that returns the point where two lines intersect
 common-point: func [l1 [pline] l2 [pline]] [
 ...
 ]

 ; function that returns the line joining two points
 common-line: func [p1 [ppoint] p2 [ppoint]] [
 ...
 ]

 ; is the given point on the given line?
 pt-on-line?: func [p1 [ppoint] l1 [pline]] [
 ...
 ]

 print [line 2 is  common-line P1 P2]  ; and get meaningful output

 P3: 2 * P1  ; by defining for REBOL what it means to multiply
 ; a ppoint by a number

If I want to define a function that takes a ppoint as an argument, I
can only say:

 some-function: func [ppt [object!] ...] [...]

but then REBOL will allow *any* object to be passed (likely giving me
a run-time error when I try to actually perform some operation on/with
it inside the function body).

Now, let's apply this idea to your list; many of your desired types
are just numbers with an associated dimensionality -- so many degrees F
(or C or K ...), yea many pounds (or grams or kilograms or stone ...),
and (with composite dimensions) thus many grams per cubic centimeter
(or miles per hour, or liters per second ...)

If we had true type support for objects, we (*any* REBOL programmer
with enough experience/determination) could write something like
(I'm making this up as an illustration, so it's not debugged! ;-)

 dimensions: make object! [
 numerators: []
 denominators: []
 to-string: func [] [...]
 ...
 ]

 dimensioned-number: make object! [
 value: 0
 units: make dimensions []
 to-string: func [] [...]
 ...
 ]

 distance: dimensioned-number 6 [mile]
 how-long: dimensioned-number .1 [hour]
 print distance / how-long ; or print divide distance how-long

and get

 60 mile per hour

Then someone who wanted to compute earth's escape velocity in
furlongs per fortnight could do so without further support from RT!

 
 * A way to access words outside of the current context. Perhaps
 extending the refinement! data-type, like:
   /Foo: 123   ; set the value of 'Foo outside this
 context to 123.
 

Could you give an example of what this means and how it would be
used/useful?  I must confess that I don't understand it at all.

 
 * Regular Expressions as well as parse, which acts much like Perl's
 regexp.
 

At the risk of sounding inconsistent, I believe that this one added
feature would do more to broaden REBOL's appeal than anything I've
seen on the list in a long time.  Even though there's some variation
in syntax (and number of extensions), REs are a core, mainstream
concept in the world I live in.  Recognizing that fact, and making a
(tiny) concession to the existing skills of the programming community
would eliminate one more excuse for serious geeks to dismiss REBOL.

 
 * Native XML! data-type.
 

My top XML wish is simply a beefed-up XML parser which does validation

[REBOL] Another coffee break problem?

2003-11-10 Thread Joel Neely

If Sunanda will allow me to steal his subject line... ;-)

The following 3-by-3 display is a simple magic square:

 0  8  4
 5  1  6
 7  3  2

because each row and each column sums to 12.  Write a function which
uses the integers 0 thru 8 (once each!) to construct all possible
3-by-3 simple magic squares.  Make it run as quickly as possible.

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: REBOL hosting

2003-11-07 Thread Joel Neely

Hi, Gabriele,

That doesn't always work...

Gabriele Santilli wrote:
 
 Unless the server is braindead (i.e. Windows ;-), you just put the
 REBOL  binary  somewhere  in  your  space (possibly out of the web
 accessible area) and use the CGI extension for your scripts.
 
 However,  having  support  from the techs is usually a good thing;
 so,  a  hosting  company  that  treats  REBOL  nicely is good news
 anyway.
 

The .cgi extension doesn't work unless the server is configured for it.
Non-braindead web servers (e.g. Apache, Netscape, etc.) don't serve cgi
scripts from user space unless specifically configured to do so.  Some
(many?) ISPs choose not to turn these options on, out of concern for
one or more of the following:

-  security,
-  wanting to prevent unskilled programmers from writing code that
consumes too much resource (e.g. cpu, ram, disk, etc.),
-  preventing their users from generating spam,
-  etc.

For many of the same reasons, ISPs often do not allow (or charge more,
or require special arramgment for) shell access.  Assuming that the
server is running A Real Operating System (e.g. Linux, Unix, et familia)
one may need shell access to make a file executable, even if one can
upload it to one's filespace.

-jn-




-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: REBOL hosting

2003-11-07 Thread Joel Neely

Hi, Gabriele,

YMMV

Gabriele Santilli wrote:
 
 JN The .cgi extension doesn't work unless the server is configured for it.
 
 Of  course,  but  a  standard  installation of Apache comes with a
 cgi-bin  directory  and  .cgi  extension preconfigured (as well as
 .pl, usually).
 

My experience has been different.  In the instances of Apache I've
worked with, the cgi-bin directory is generally writable only by
the admins, not by users in general, and .cgi service from user
directories has to be enabled (is not enabled by default).

 
 JN Assuming that the
 JN server is running A Real Operating System (e.g. Linux, Unix, et familia)
 JN one may need shell access to make a file executable, even if one can
 JN upload it to one's filespace.
 
 Usually FTP does it nicely, you just need a decent FTP client.
 

Only if you're coming from another Linux/Unix/etc box.  If you FTP
from a 'doze box, the bits aren't set IME.

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Coffee break problem anyone?

2003-11-07 Thread Joel Neely

Hi, Sunanda,

[EMAIL PROTECTED] wrote:
 
 Your point is that it is usually best to start with the data
  structures. I'd  agree. But it isn't always that simple.
 

I agree.  Sorry for not being more precise.  What I should have
said (adding the omitted conditions/details) was:

 For problems where the input/output (or argument/result)
 data structures are already defined, it is usually very
 helpful in design, implementation, and maintenance to
 use the I/O (a/r) structures as much as possible as guides
 for the algorithm structure.

 This approach usually helps minimize redundant code, gives
 unambiguous guidance to where each part of the code should
 be placed in the algorithm, and minimizes the risk of bugs
 arising from accidental mismatches between the flow of the
 algorithm and the flow of the data.

Of course, in cases where the nature of the data are somewhat
up in the air (e.g. the problem is more vaguely specified,
or the designer is given latitude to choose data/representation
structures) there's clearly not so much heuristic guidance.

Also, if the structure of the data changes, it may imply
significant rework of the program.

 
 The actual original task was to find the best why to describe
  the differences between two version of the same file. There is
  a lot of subjectivity there.
 

That's exactly what I meant by not well-defined.  I don't mean
that as a negative description, but simply as an indication that
there may be a period of more exploratory programming to try
different ideas before choosing one as the basis for final design
and implementation (or that the program may very well simply
evolve, as various ideas/heuristics are added and tweaked).

I suggest that in such a case, there's benefit from a program
structure that makes it easy to figure out where to put such
heuristics (and where to find them when its time to change or
delete them;-)

 
 But best and better depend on the resources available.
  In this case, they are a little restricted:
 

Again, we'll certainly agree that the juggling and comprimises
made when shoehorning a 10-pound algorithm into a 5-pound
interpreter are at least as much art as science!  ;-)

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: syntax across languages

2003-11-06 Thread Joel Neely

Hi, Maarten, and all,

There's a serious question at the end of all the yammering below!  ;-)

Maarten Koopmans wrote:
came accross an interesting site on syntax across languages
which is soliciting help with constructs in various languages
including rebol.
They are currently missing 120 syntax constructs for rebol.
 
 Most of them are available in REBOL but not in the comparison. If I only
 had time...
  

I can relate!

On the other hand, I'm also ambivalent their terminology; the table of
contents maintains the syntax pretense, but there are really three
different levels being addressed (somewhat indiscriminantly):

1 lexical rules (e.g. structure of a user-defined name/word)
2 higher-order syntax (e.g. structure of an if statement)
3 language features (e.g. get type/class [of] object/instance/value)

I'd be glad to be updated, but I haven't seen (1) fully documented
anywhere for REBOL.  (Remember recent -- and not so recent -- posts
about what characters are allowed in a word?  IIRC most such questions
get resolved by trial and error or advice from someone who's already
traveled that road, not by pointing to section x.y in the manual.)

As for (2), it doesn't exists!  I'm not trying to be pedantic here,
but sincerely believe that one of the early steps to getting REBOL
is to realize that e.g. THERE IS NO IF STATEMENT, but merely some
functions (IF, IF/ELSE, EITHER) that take an argument of type
[LOGIC! NONE!] and one or two arguments of type [BLOCK!] and, if you
so choose, YOU CAN WRITE YOUR OWN.

Being pragmatic, I know that a short answer to the question:  How
can I say the likely equivalent of

 if (buff [0] == '\0') {
 p--;
 } else {
 p = q % ++r;
 }

is

 either zero? length? buff [
 p: p - 1
 ][
 p: q // r: r + 1
 ]

but that doesn't necessarily help the questioner make the leap to

 p: either zero? length? buff [
 p - 1
 ][
 q // r: r + 1
 ]

or even more REBOL-ish reconceptualizations of the programming task.

That brings me to (3), where IMHO it becomes most clear that efforts
such as the page in question often become either too encylpaedic for
ease of use, or else too superficial for useful ... use.  It's one
thing to take two languages that share most of their conceptual base
(e.g. Pascal and C, ALGOL and Pascal, etc.) and address in a fairly
complete way the questionS (plural emphasized):

- What are the correspondences between the languages (i.e. for those
   features that are conceptually similar, how does one respell
   from one notation to the other)?  In this category, explaining that
   Pascal uses begin ... end for sequences of statements, while C
   uses { ... } is reasonable.

- What are points of NON-CORRESPONDENCE between the languages, and what
   effect does that have on one's programming/design thinking?  In this
   category, the nesting of lexical scope (e.g. procedures defined
   locally to enclosing procedures in Pascal, vs. the flatter, assembly-
   like model of C) can cause one to think and design quite differently.

I should also add that many of the issues under the second point above
often become significant when [only when?] designing programs that deal
with larger-than-toy problems.

But when approaching languages with substantially different conceptual
models, the second issue becomes so dominant that the first issue is
either irrelevant or misleading IMHO.  For example, what is the REBOL
equivalent for the elementary PROLOG idiom

 conc( [], L, L ).
 conc( [X | L1], L2, [X | L3] ) :- conc( L1, L2, L3 ).

???  As much as we might like to write

 conc: 'join

that just won't cut it, when trying to understand why

 last( Item, List ) :- conc( _, [Item], List ).

works.

Inspired by discussions on this list, I started putting together some
recipes for a Perl-to-REBOL cookbook.  I say started because I was
smacked in the face by the above issues on the very first recipe, which
dealt with the Perl substr function.  You see, in Perl, substr can be
used both as an lvalue and an rvalue (a distinction which doesn't exist
in REBOL).

And OBTW, using an rvalue string expression as an rvalue in
Perl implicitly copies, while an lvalue string expression mutates...

And OBTW, the Perl splice function (more or less) does for
arrays what substr does for strings, but REBOL blocks are the closest
analog to arrays, and block! and string! types are both subsumed in the
REBOL meta-type series! so instead of defining SUBSTR, shouldn't one
actually define SUBSER and ...

So instead of a one-page recipe, I suddenly had a very long chapter (I
know you can't believe that I found lots to say on such a narrow topic
;-) and began to question whether anyone would bother to read it!  On
the other hand, I don't want to spend the effort to produce something
that ends up being so superficial that it's a read-once-and-throw-away
(as is the case with too many books and articles in the computing
field 

[REBOL] Re: syntax across languages

2003-11-06 Thread Joel Neely

Hi, Maarten...

Maarten Koopmans wrote:
 
 Wow! You can do a 
 
 bind 'word [ multiple values ] 
 
 in your real life?
 

multitask-into-stress: func [word [word!] selves [block!]] [
 forever [
 foreach role selves [
 do get in role word
 ]
 ]
]

; -)

 
Any/all feedback/comments are welcome!

 
 Are the alternatives or refinements? Oops... my lexer got stuck (again)
 ;-)
 

It's just a different dialect!  ;-)

-jn-



-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Coffee break problem anyone?

2003-11-05 Thread Joel Neely

Hi, Sunanda,

First, let me offer an improvement and then address some more of the
good discussion points you raise.  (There's a little challenge at
the end for the interested who wade through to that point! ;-)

Minor issue first: instead of initializing run length to zero and
incrementing for each added element, just directly calculate the
length once the run is finished.

Now for the more interesting stuff...

Instead of saying that:
- a block is an iteration of runs, and
- a run is an iteration of numbers;

 block --*-- run --*-- number

lets say that:
- a block is an iteration of runs, and
- a run is a first number, followed by any consecutive numbers.

+-- first number
|
 block --*--+
|
+--*-- consecutive number

This (again) addresses a boundary issue; the first value in a run
plays a different role than the other numbers in the run.  Tricky
setup of initial conditions so that the first value can be treated
just like all the others adds more complexity to the code.

That said, here's a version that implements that view:

 where-j: func [
 block [block!]
 /local maxpos maxlen runpos runlen prev curr
 ][
 maxpos: maxlen: 0 ; default empty run
 while [not empty? block] [; more data = more runs
 runpos: index? block  ; start new run here
 prev: block/1 ; remember first value
 block: next block ; done with first
 while [
 prev + 1 = curr: block/1  ; extending the run
 ][
 prev: curr; save comparison value
 block: next block ; move on
 ]
 runlen: (index? block) - runpos   ; now compute length
 if runlen  maxlen [  ; update best run?
 maxpos: runpos
 maxlen: runlen
 ]
 ]
 reduce [maxpos maxlen]; return best run
 ]

[EMAIL PROTECTED] wrote:
 
 ... the insight that (in effect) the procedures can fall naturally out of an 
 analysis of the data structures can lead to some very elegant solutions.
 
 Of course there are situations where neither approach works, and then you 
 need other approaches too. Object-orientation is one claim to the next step as it 
 merges both approaches.  I never quite saw the point there, either, but it 
 does work in some areas.
 

I'm not clear on what you mean by both approaches...  I view JSP
(Jackson Structured Programming) simply as a specific type of
structured programming which has strong heuristics about which
structure(s) should drive the design.

 
 And then there are situations that seem completely off the
  deterministic axis.
 

??? Do you mean non-deterministic programming, or just programming
when the criteria are only vaguely stated?

   Consider this progression:
 
 -- Find the sum of the numbers (simply almost any way: write a loop;
  use a  map function, etc)
 

Easy.  Agreed.

 
 -- Find the longest run with the highest end value (101--107 in the
  original data)
 

An easy extension of the above program:

- add a local MAXTOP initialized to anything
- change the condition at the end from
  runlen  maxlen
   to
  any [runlen  maxlen  all [runlen = maxlen prev  maxtop]]
- change the new best run block to include
  maxtop: prev

(For why this was easy, see below...)

 
 -- Find the run (as defined in the original problem) whose run length
  is the modal length of runs
 

First, we have to change the run to a run, since the answer is no
longer unique.  For the data

 [10 8 9  6 7  4 5  0 1 2]

there are runs of length 1, 2, 2, 2, and 3, so the mode length is 2,
and there are three runs that have that length.

However, something more significant has happened.  The previous change
to the problem (longest run with highest upper value) actually had THE
SAME STRUCTURE as the original problem: find the best run, where we
have a simple test for determining whether one run is better than
another.  In other words, we can generate runs one at a time, and test
each one against the current best to see which one wins.

But in this last change, we now are asking for a run based on some
property/ies of the entire collection of runs, so we must generate (and
retain) all of them.  We can (trivially) change the above function to
return all runs, then write a separate pick a median function to
operate on that collection (or we build the additional stuff into the
end of the modified function).  In either case we now have a two-step
approach:

1)  transform the offered block into a collection of runs;
2)  do something with the collection of runs.

That's why the first change was easy and the second one was harder.

 
 --Find the two runs that are most nearly similar (contain mostly the
  same  numbers)
 

I think I 

[REBOL] Re: Hitting the learning curve

2003-11-05 Thread Joel Neely

Hi, Volker,

Volker Nitsch wrote:
 Am Mittwoch, 5. November 2003 18:56 schrieb Steven White:
...  So to easy my confusion I type all the REBOL words in lower case
  and all the words of my own invention in upper case, just like old
  COBOL.  It is not recommended as a style, but it helps me personally.

 
 There is a script somewhere, %colorize.r? rebol.org? it takes a script
  and outputs colored html. words found in rebol itself have a diferent
 color.AFAIK. could be used/modified to show scripts with your own
  words more marked up.
 

All of the above is more reason to use vim (or some other equivalent
editor) that does syntax coloring.  My normal development environment
for REBOL is one or more vim windows (or terminal windows with vi[m]
running in it/them, depending on platform) and a REBOL console.  The
edit/test cycle simply toggles between windows, and the syntax coloring
is always there (without the need to run some utility to get a static
view of the code that's outdated with the next editor keystroke).

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: function to object?

2003-11-05 Thread Joel Neely
] [
 count: usages: 0
 foreach object object-inventory [
 print [
 object with factor object/constant
 was used object/usage
 times
 ]
 count: count + 1
 usages: usages + object/usage
 ]
 print [count objects used a total of usages times]
 ]

which gives us

  inventory-usage-report
 object with factor 2.54 was used 1 times
 object with factor 4.546 was used 2 times
 2 objects used a total of 3 times
 

And (assuming we actually re-used the same name for our factory
instead of changing the name every time, as I did above for the
purpose of explanation) we accomplished this without changing any
of the code that used PRODUCT-FACTORY (the standardized name).

Of course, if there's no state that persists between evaluations,
using an object seems overkill... or does it?

The other nice thing that an object does for us is to provide a
private namespace, which allows us to decompose a complicated
function into an interface function that uses a collection of
(hidden) helper functions and values shared among those functions
without cluttering up the global namespace with all of those
implementation details.  The QAD above left OBJECT-INVENTORY in
the global namespace, whereas

 general-products: make object! [
 inventory: []
 manufacture: func [a [niumber] /local obj]] [
 append inventory obj: make object! [
 constant: a
 usage: 0
 f: func [b [number!]] [
 usage: usage + 1
 times constant b
 ]
 ]
 get in obj 'f
 ]
 report: func [/local count usages] [
 count: usages: 0
 foreach object inventory [
 print [
 object with factor object/constant
 was used object/usage
 times
 ]
 count: count + 1
 usages: usages + object/usage
 ]
 print [count objects used a total of usages times]
 ]
 ]
 product-factory: get in general-products 'manufacture

so now the rest of the world doesn't need to know or worry about the
block holding the inventory, and the INVENTORY-USAGE-REPORT doesn't
conflict with the warehouse database.  ;-)

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Coffee break problem anyone?

2003-11-04 Thread Joel Neely
 maxlen: seqlen  ; ... and length
 ]
 ]
 reduce [maxpos maxlen]
]

Notice that now there's a single, obvious place for the test for new
best run -- right after the inner loop across a run's numbers!  The
condition on the inner loop has to satisfy the outer loops condition
first, and then add its own criteria (which uses ZERO? SEQLEN to mean
that we have a new run, and therefore don't care whether the previous
value was one less than the current one).

To see the value of this structural change, imagine that we now need
to return a triplet of numbers; in addition to the position and length
of the longest consecutive run, also return the count of how many runs
of that length existed.  Where would that code go in the Jackson
version?  Where would it have to appear in the other one?

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Formatting a display line

2003-11-04 Thread Joel Neely

Hi, Steven,

The typing of the parameter has already been pointed out, but
let me give you a speed improvement as well.

Using SOURCE shows us that APPEND is essentially INSERT TAIL
(just what you'd expect), and INSERT has a /DUP refinement that
duplicates the insertion, so instead of ...

Steven White wrote:
 
 ADD-FILLER: func [
 Add a specified number of blanks to FORMATTED-LINE
 SPACE-COUNT integer!
 ] [
 PRINT [NOW WE WILL ADD  SPACE-COUNT  SPACES]
 loop SPACE-COUNT [
 append FORMATTED-LINE;; 
 PRINT [FORMATTED LINE IS  LENGTH? FORMATTED-LINE 
 BYTES: FORMATTED-LINE]
 ]
 ]
 

... just define ...

add-filler: func [
 add specified number of spaces to formatted-line
 space-count [integer!]
][
 insert/dup tail formatted-line   space-count
]

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Bidirectional value mapping.

2003-11-03 Thread Joel Neely

Hi, Bruno,

I know of no way to avoid some duplication.  See below.

Bruno G. Albuquerque wrote:
 
 I have 2 values that would be mapped to each other. What I need to do is
 to be able to find the first valeu by searching for the ceond and locate
 the second by searching for the first. I did come up with solutions to
 that but I am not satisfied with any of the solutions. Is there a standard
 Rebol-Way ofr doing that? The best option would be a way that would not
 result in data duplication.
 

The answer somewhat depends on details of your problem; if forward
and reverse mappings are distinct (as in translating between host
names and IP addresses, or encoding and decoding with a non-symmetric
encryption scheme) then the simplest thing to do is keep both maps
as separate blocks (or hashes):

  roman2number: [i 1 v 5 x 10 l 50 c 100]
 == [i 1 v 5 x 10 l 50 c 100]
  number2roman: [1 i 5 v 10 x 50 l 100 c]
 == [1 i 5 v 10 x 50 l 100 c]
  select roman2number x
 == 10
  select number2roman 10
 == x

If you know which way you're mapping, you just select the appropriate
map.  (Of course, it's easy to write a function that would take one of
the above and give the other, so you don't have to create both by hand.)

NOTE!!!  That last sentence is only true if the mapping is an invertable
function!!!  If, instead, you have a many-to-one (e.g. letters to the
words consonant or vowel) of course there's no way to invert.  I
assume you know that, but want to include that warning for completeness.

The other (perhaps slightly more REBOLish) way to do this is to inter-
leave the forward and reverse mapping values as follows:

  roman-numerals: [
 i 1 i v 5 v x 10 x l 50 l c 100 c
 ]
 == [i 1 i v 5 v x 10 x l 50 l c 100 c]
  select roman-numerals x
 == 10
  select roman-numerals 10
 == x

This works nicely for such things as ROT13, which is a self-inverse
mapping (and again, you can write a utility function that would take
e.g. ROMAN2NUMBER above and give you the interleaved ROMAN-NUMERALS).
However THIS DOES NOT WORK IN GENERAL if the domain and range of your
mapping overlap.  As a simple example, consider the trivial example of
rotating among three elements:

 forward: [a b c a]
 reverse: [c b a c]

Since a maps to b going forward, but b maps to c going forward,
then both forward and reverse mappings can't be combined into a single
block/hash.  To see why this is true, consider what would have to follow
b in the combined series!

Unless you know you have a self-inverse mapping and you consider speed
soo important that you'll sacrifice readability for performance,
I recommend using distinct forward/reverse mappings (with a helper to
construct the inverted one).  It'll be easier to read anyway!

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: check me? deleting files based on a pattern

2003-10-28 Thread Joel Neely

Hi, Tom,

Saving some typing and evaluation...

Tom Foster wrote:
 
 home: to-file rejoin [~ /]
 
 base: to-file rejoin [home attempt-it/]
 
 foreach file read base [
 if found? (find file editpost) [
 delete base/:file
 ]
 ]
 

You can just use a literal FILE! value for the base directory

 foreach file read base: %~/attempt-it/ [...[

and avoid all the REJOIN evaluations.

-jn-


-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Storing a logical condition

2003-10-21 Thread Joel Neely

Hi, Brett,

Actually, you remind me of another point which I failed to raise...

Brett Handley wrote:
 
 ...  result encourages one to use a form that has the least effect
  on the parent/calling expression - whether you evaluate the
  condition early eg:
 condition-result: dummy = 1
 or you evaluate it late using the function:
 condition-result: does [dummy = 1]
 
 Your parent expression eg.
 print condition-result
 
 Need not change (unless of course dummy does). A nice finding.
 

That also points out another drawback of the

 any [expr]

and

 all [expr]

versions; they do not preserve the type of (the evaluation of) EXPR
for FALSE values, but yield NONE instead!  This can become an issue
in various ways, such as causing erroneous results when comparing
with LOGIC! values from other expressions (FALSE does not equal NONE)
or causing type errors when handing off to a mezzanine which expects
a LOGIC! argument.

While there are workarounds based on standard boolean identities:

 true and all [expr]

or

 false or all [expr]

they simply obscure what is being expressed, IMHO.

Per the extreme guys, Do the simplest thing that could possible work!

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: reduce/deep

2003-10-21 Thread Joel Neely

Hi, Robert,

Robert M. Münch wrote:
 
 Hi, ahhh forgot about this one. Rebol just has to many words to remember 
 ;-) But this doesn't seem to work for nested blocks:
 

Sure it does!

 
d: reduce [a b]

 == [[a 1 b 2] [a 1 b 2]]
 
e: reduce [a b]

 == [[a 1 b 2] [a 1 b 2]]
 
same? d e

 == false
 

Consider a simpler, analogous set of evaluations:

  a: b: xyz== xyz
  same? a b  == true
  c: reduce [a b]== [xyz xyz]
  d: reduce [a b]== [xyz xyz]
  same? c/1 d/1  == true
  same? c/2 d/2  == true
  same? c d  == false
  equal? c d == true

or even *more* simpler (pardon the grammar!  ;-)

  p: 12  == 12
  q: 12  == 12
  same? p/1 q/1== true
  same? p/2 q/2== true
  same? p q== false
  equal? p q   == true

These all illustrate the difference between SAME? and EQUAL? in that
it is entirely possible to have two different series values whose
corresponding elements are the same.  In my first example above,
as in your original post, two different REDUCE expressions over two
different blocks will not produce THE SAME block, even if the content
of those two blocks are the same.  However the blocks are equal.

My second example breaks it down even further.  Two different
appearances in the input of

 12

correspond to two different strings, even though the corresponding
characters in those strings are equal (and same, being immutable).

Likewise, two different appearances of

 [a b]

result in the creation of two different blocks, even though the
corresponding words in those blocks are the same.  Therefore, when
we reduce those distinct but equal blocks, we get distinct but equal
resulting blocks.

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1



-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Storing a logical condition

2003-10-20 Thread Joel Neely

Hi, Tim, and all!

My buffer overflowed, but maybe this is still worth posting...

Tim Johnson wrote:
 * Brett Handley [EMAIL PROTECTED] [031013 16:42]:
Like Ingo's observation, it is significantly faster too - significant if you
have a million iterations ;^)

 timeit [repeat i 100 [do b]]
== 0:00:04.387
 timeit [repeat i 100 [all b]]
== 0:00:02.604
 
   Cool! Who woulda thunk it?
   That's a good tip.
   thnx
   tim
 

Using a block specified as

 blk: [dummy = 1]

and a function defined as

 fn: func [] blk

I compared the runtimes of

 loop reps []  ;; to deduct loop overhead
 loop reps blk ;; in-line
 loop reps [do blk];; do
 loop reps [first reduce blk]  ;; first reduce
 loop reps [fn];; fn
 loop reps [any blk]   ;; any
 loop reps [all blk]   ;; all

After deducting the loop overhead from all other timings (average of
ten) I calculated the ratio of each relative to the inline case.  I
tested with DUMMY equal to 1 and 2 (just in case there was an effect
on ANY or ALL), but found no significant difference.  Timings were
done on an Athlon 2400 running wXP, with REPS set to ten million.

I was surprised (and educated) by the result for one version!

 versionavg time   ratio to in-line
       
 in-line 1.827 s   100.0%
 fn  3.067 s   167.9%
 any 3.826 s   209.4%
 all 3.869 s   211.7%
 do  3.998 s   218.8%
 first reduce   15.771 s   863.1%

Yep!  The winner is the lowly, plain-vanilla function!  At least for
this simple case, the fastest way to defer the evaluation of an
expression is simply to make that expression the body of a function
with no parameters!

I guess sometimes we outsmart ourselves!  ;-)

-jn-


-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Multithreading with Rebol

2003-10-17 Thread Joel Neely

Hi, Robert,

A couple of thoughts on the other side...

Robert M. Münch wrote:
 
 Hi, don't bee fooled by all this multi-threading hype. For example,
  have a look at www.xitami.com and theire LRWP protocol. This is done
  using a  cooperative multi-tasking. Very cool and fast, and it can
  be coupled with Rebol quite easy.
 

I don't know what you mean by hype, nor what that has to do with
speed.  I've never thought of parallelism in terms of the speed of a
single task, but as a design/expressiveness issue.

Remember: it's possible to express *any* computation in terms of only
sequence, alternation, and iteration (e.g. block, IF, and WHILE) but
few of us choose to restrict ourselves to only those mechanisms.  For
that matter, most of us would prefer to write (e.g.):

 foo: func [b [block! n [integer!] ...] [
 ... expressions with B and N ...
 ... final expression with B and N
 ]
 ...
 blort: foo someblock 23

instead of

 foo-b: foo-n: foo-result: none
 foo-exprs: [
 ... expressions with B and N ...
 foo-result: ... final expression with B and N
 ]
 ...
 foo-b: someblock
 foo-n: 23
 do foo-exprs
 blort: foo-result

The gain in expressiveness from having functions renders irrelevent
the contention that we could find other ways to get the job done
without them.

There are some problems whose solution can be most naturally
expressed in recursive terms.  Likewise, there are some problems
which can be expressed most clearly as a collection of distinct
processes with well-defined collaboration patterns.  Consider the
popularity of | as a means of structuring computations via the
*nix shell.  Of course, anything that can be done with | can also
be done in a single-threaded program, but then the programmer has
to concern herself/himself with implementation/algorithm details
that are simply irrelevant at the level of the original problem
(e.g. buffering, distinguishing push-driven and pull-driven
variations of the same algorithm, etc.)

Finally, there are cases in which one of a set of collaborating
activities should be allowed to stall for a time without forcing
all others to wait.  The fact that we can (sometimes!) deconstruct
our code in a scheme to allow this to be managed in a single thread
only means that we now have to add the issues of that scheme to the
things to consider in doing our design, instead of being able to
keep our focus on the top problem.

I've recently been involved in several (very hard-core practical)
projects where parallelism made significant contribution to the
simplicity of the solution, overall performance, or both.


 Remember: multi threading won't solve performance problems just
  because  it's multi threaded...
 

Agreed, but...

Remember: single-threading won't solve design problems just because
only one thing is happening at a given instant!  ;-)

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Counting lines of code is to software development as
counting bricks is to urban development.



-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Compose on tag! values

2003-10-15 Thread Joel Neely

Hi, Andrew,

Here's a QAD RYO...

Andrew Martin wrote:
 What do people think about extending 'compose to work within tag!
 values? For example:
 
   paragraph_colour: green
   compose [
   p style=Color: (paragraph_colour);
   ]
   which results in:
   [
   p style=Color: green;
   ]
 

One function definition...

compose-tag: func [blk [block!]] [to-tag rejoin compose blk]

...after which...

  paragraph_color: green
 == green
  compose-tag [{p } {style=Color:} (paragraph_color) {}]
 == p style=Color:green

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Counting lines of code is to software development as
counting bricks is to urban development.


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: pleac

2003-10-13 Thread Joel Neely

Thanks, Andreas!

Andreas Bolka wrote:
 
rot13: func [s [string!]] [
 foreach char s [
 prin any [
 select/case anabobcpcdqderefsfgtghuhivijwjkxklylmzm char
 select/case AZABOBCPCDQDEREFSFGTGHUHIVIJWJKXKLYLMZM char
 char
 ]
  ]
 prin newline
]
 
 
 sorry the nit-picking, but i guess the first #Z in the second
 sequence should rather be an #N :)
 

You're absolutely right.  I didn't proofread (or test enough)!

-jn-



-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: pleac

2003-10-12 Thread Joel Neely

Hi, Carl,

How about a slightly more REBOL-intensive variation?

Carl Read wrote:
 
 Going by most of the examples I've checked on the site it seems they'd
 like characters to be printed one at a time, so here's a modified
 version of the script I just posted...
 
 rebol []
 
 foreach char input [
 letter: to-string char
 if all [letter = a letter = z][
 char: char + either letter  n [13][-13]
 ]
 prin char
 ]
 prin ^/
 

rot13: func [s [string!]] [
 foreach char s [
 prin any [
 select/case anabobcpcdqderefsfgtghuhivijwjkxklylmzm char
 select/case AZABOBCPCDQDEREFSFGTGHUHIVIJWJKXKLYLMZM char
 char
 ]
  ]
 prin newline
]




-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: pleac/rot13

2003-10-12 Thread Joel Neely

Hi, Norman,

Here's one way, but I don't know about smallness...

Rebolinth wrote:
 
 A honarable listing on the one that builds the smallest ROT13 using bitsets and 
 parsing ;-)
 

r13: func [s [string!] /local left right neither r13char c] [
 left: charset [#a - #m #A - #M]
 right: charset [#n - #z #N - #Z]
 neither: complement union left right
 r13char: [
 [ copy c left (c: +13 + to-char c)
 | copy c right (c: -13 + to-char c)
 | copy c neither]
 (prin to-char c)
 ]
 parse s [any r13char]
]

-jn-




-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Newbie expression question

2003-10-11 Thread Joel Neely

Hi, Sunanda,

Minor quibble below...

[EMAIL PROTECTED] wrote:
 Kai:
 
if length? tlist/data  1000
 
 Can someone give me a pointer as to what i need to do?
 
 
 Try these:
 
 if (length? tlist/data)  1000
 or 
 if 1000 = length? tlist/data
 

I think you meant

 if 1000  length? tlist/data

as equality isn't in the other cases.

-jn-



-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Newbie expression question

2003-10-11 Thread Joel Neely

Ooops!  I hit the send button before finishing...

[EMAIL PROTECTED] wrote:
 
if length? tlist/data  1000
 
 Try these:
 
 if (length? tlist/data)  1000
 or 
 if 1000 = length? tlist/data
 
 
 (I always go for the (...) solution as I can't be bothered with reversing 
 boolean operations.
 

I've been experimenting lately with restricting myself to using only
 and = to express ordered comparisons.  There were a couple of initial
reasons for the experiment:

- as the number line (conventionally pictured, anyway!) contains smaller
   values on the left and larger values on the right, I wanted to test
   the mnemonic value of writing expressions with smaller/left and
   larger/right ordering;

- it gives compound and range conditions a natural form:

  ... all [lowerlimit = testvalue  testvalue = upperlimit] ...

   which resembles the normal mathematical notation:

  lowerlimit = testvalue = upperlimit

   (the only languages I can recall at the moment that understand that
   notation would be Python and Icon).

- it's an interesting psychological experiment; mathematically the two
   expressions (e.g.)

   a  b

   and

   b  a

   are equivalent, so why is it that so many of us have learned to
   feel more comfortable with

   foo  100

   than

   100  foo

   in our programs?  Is it because our natural language habits make
   us subconsciously think of the expresson(s) above as being more
   about FOO as the subject of the sentence, rather than about the
   relationship between two equally-important values?

At any rate, it also has the interesting side effects that many REBOL
expressions no longer need parentheses.  It's also interesting to see
the effect on one's thinking from deliberately breaking almost sub-
conscious habits.

-jn-




-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: IDIOMS: setting multiple words

2003-10-10 Thread Joel Neely

Hi, Elan and all,

Elan wrote:

 Hi Sunanda:
 

set [foo bar baz] copy []
 
 You will find that only foo is set set to a block, whereas bar and baz 
 are initialized to the value none. This is unlike using
 set [foo bar baz[] 3 ;- (i.e. some non-series value
 where all words will be initialized to the same value.
 

Actually, all of FOO BAR and BAZ will be set to NONE, as the empty list
is the source of *all* values for the three words:

  set [foo bar baz] copy []
 == []
  foo
 == none
  bar
 == none
  baz
 == none
 

-jn-



-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Accessing a variable's method

2003-10-10 Thread Joel Neely

Hi, Arnoux

It's simple (simpler than that, actually ;-)

Arnoux Vincent wrote:
 Hi List,
 I have a list of objects:
 /l: copy []
 obj: make object! [ a: none calc: does [self/a: (self/a + 1)]]
 append l make obj [a: 1]
 append l make obj [a: 2]/
 
 I would like to write a function like:
 /inc-obj: func [arg][
 arg/calc
 ]/
 
 That would allow me to do:
 /foreach o l [
 inc-obj o
 ]
 /
 And output:
 /probe (first l)/a/
 /2
 //probe (second l)/a/
 /3
 
 /Is it possible ?
 

Yes, and you don't need the overhead of INC-OBJ or the repeated uses
of SELF within the method on your objects.  See transcript below:

  proto: make object! [
[count: 0
[bump: func [] [count: count + 1]
[]
  obj-block: []
== []
  repeat i 4 [append obj-block make proto [count: i]]
== [
 make object! [
 count: 1
 bump: func [][count: count + 1]
 ]
 make object! [
 count: 2
...
  foreach obj obj-block [obj/bump]
== 5
  foreach obj obj-block [print obj/count]
2
3
4
5
 


-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Counting lines of code is to software development as
counting bricks is to urban development.


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Tail end recursion

2003-10-09 Thread Joel Neely

Hi, Maxim, and all

Maxim Olivier-Adlhoch wrote:
 so basically its like using recursion to do a loop?

...
 but how does tail-end recursion stop?
 

Recursion and looping are just two ways of expressing that something
is to be repeated.  In both cases one needs a terminating condition
(unless the process is to run forever...)

The example given earlier was a tad to trivial to make that point,
but consider instead the slightly more complete example:

 forr-count: func [limit [integer!]] [
 for i 0 limit 1 [print i]
 ]

As we all know, this is just syntactic sugar for:

 while-count: func [limit [integer!] /local i] [
 i: 0
 while [i = limit] [
 print i
 i: i + 1
 ]
 ]

Notice that this version clearly states the initial state (I = 1),
the condition for continuing the computation (I = LIMIT), and the
evaluation to occur for each continued case (PRINT and increment).

Those same three ingredients are required to write an equivalent
recursive function:

 rec-count: func [limit [integer!] /local .rec-count] [
 do .rec-count: func [
 i  [integer!]
 .limit [integer!]
 ][
 if i = .limit [
 print i
 .rec-count i + 1 .limit
 ]
 ] 0 limit
 ]

Notice that every evaluation path through the inner function
(.REC-COUNT) either terminates the computation or ends with a
recursive call on itself, and every call to the inner function
is the last thing in an execution path.  (There's one of each.)
In such cases, some languages/implementations can avoid the
state-saving/restoration normally associated with beginning a
subordinate evaluation -- in other words, they transform the
recursive inner function above into a loop.  REBOL does not.

Sometimes the clearest/simplest specification for how to solve
some problem is based on a divide-and-conquer strategy, where
the sub-problems are either trivial to solve or are smaller
cases similar to the original problem.  In these cases, it is
often easier to write a recursive solution.  If the state
management of the recursive implementation is too costly, one
can (attempt to! ;-) formally transform the recursive solution
into an iterative one; sometimes that's easy and sometimes not. (*)

For more on this subject, please see

 http://www.rebolforces.com/articles/ria/

and for more on why recursion isn't complicated, see

 http://www.rebolforces.com/articles/metaphors/


HTH!

-jn-

(*) For an example of a problem that's easy to solve recursively,
but which takes a bit of thought to solve iteratively (or in closed
form! ;-), consider the old Fibonacci numbers.  The original problem
can be framed as follows:

 Begin a pair of new-born rabbits (one male, one female).  When a
 pair of rabbits reaches age one month, they begin breeding, with
 a one-month gestation period, and breeding again immediatly after
 birth.  Each breeding produces a pair of rabbits (one mail, one
 female).  How many pairs of rabbits does one have each month
 (assuming that rabbits are immortal, food is infinitely available,
 etc...)

Classify them as mature (at least one month old, breeding every month)
and immature (just born, not mature for one more month).  This give
us the following population chart (in pairs):

Month  Mature  Immature  Total
-  --    -
 1   0 1  1
 2   1 0  1
 3   1 1  2
 4   2 1  3
 5   3 2  5

etc...  In other words, all pairs (immature or mature) which were alive
last month are still alive, and all mature pairs from last month have
produced new pairs.  But the mature pairs last month are just the total
population the month before!  Finally, during the first two months we
only have the original pair (immature or mature), so we get

 rfib1: func [n [integer!]] [
 either n  3 [1] [(rfib1 n - 1) + (rfib1 n - 2)]
 ]

A little programming algebra produces the equivalent iterative form

 ifib1: func [n [integer!] /local a b] [
 a: 0  b: 1
 loop n [
 a: (b: b + a) - a
 ]
 a
 ]

But it takes a bit more mathematics to produce the equivalent closed
form solution

 cfib1: func [n [integer!] /local r] [
 r: square-root 5
 ((1 + r / 2) ** n) - ((1 - r / 2) ** n) / r
 ]

So recursion and iteration both have their places!  ;-)

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Counting lines of code is to software development as
counting bricks is to urban development.


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: IDIOMS: setting multiple words

2003-10-09 Thread Joel Neely

Hi, Greg,

Gregg Irwin wrote:
 
 Scenario:
 
 You have a number of words that you want initialized to copy [] or
 some other value. Do you do it like this?
 
 foo: copy []
 bar: copy []
 baz: copy []
 
 Or like this?
 
 foreach word [foo bar baz][set word copy []]
 
 Or something else.
 

Occasionally I might write

 foo: copy bar: copy baz: copy []

to emphasize that they're all alike in some way.  That also scales
well if the intial value is more complex than [] (especially if it
must be computed, but that value -- or a copy -- is needed for more
than one variable).

Otherwise, I'd probably use your first case.

 
 Do you use a different approach for more or less words?
 

If I had more words than the above, I'd start looking at whether I
needed to redesign so that they all were parts of a larger data
structure, rather than individual words.

 
 Do you do things differently if you're setting words in a object?


When setting up an object, I usually prefer the

 foo: ...
 bar: ...
 baz: ...

format to make the members of the object very clearly visible.

 
 Do you do something different based on the initial value?
 
 Is there anything else you take into consideration when you do this
 kind of thing?
 

For both of these, see above comments re scaling and number of
distinct copies.

 
 Thanks for playing!
 

Thanks for asking! ;-)

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Counting lines of code is to software development as
counting bricks is to urban development.


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: help with function utilising extended life-time words ..

2003-10-02 Thread Joel Neely

Hi, Petr,

Petr Krenzelok wrote:
 
 Thanks all for answers! I was just thinking in a bit different way - I
 did not want to enclose measured task into special block to prevent
 myself from forgetting to include ending bracket :-)
 

However, the presence of explicit brackets makes it clear precisely
what you mean when inserting or removing a call to the timer.
Without that hint, presence/absence of a call could affect the results
of other calls in hard-to-track-down ways.

 
 So, my initial intention was to have how-long? just marking current time
  substracted from last function call ... From the various aproaches I saw
  I like object based the most probably ... do not why though :-)
 

I prefer to use objects to manage persistent state precisely because
that is what objects were intended for in the first place.  The amount
of state can scale up gracefully as one's design evolves (e.g. add one
more attribute to the object) without requiring lots of tricky digital
plumbing (e.g. the REDUCE... issue at the beginning of this thread).

Just MHO, of course!  ;-)

-jn-




-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: help with function utilising extended life-time words ..

2003-10-01 Thread Joel Neely

Hi, Petr,

Here are a couple of simple approaches (which you can complicate
as desired for more functionality ;-)

-jn-

Petr Krenzelok wrote:
 
 start: now/time/precise  do something ... print now/time/precise - 
 start start: now/time/precise
 
 
 I wanted to write myself short logger function, which will save me from 
 repeating above sequences, as the script becomes a bit messy then. So I 
 wanted to have following interface:
 
   how-long? Some task ...
 

Single-task timing doesn't require any tricky state:

   how-long?: func [msg [string!] to-do [block!] /local timing] [
   timing: now/time/precise
   do to-do
   timing: to-decimal now/time/precise - timing
   print [timing msg]
   ]

Which behaves as in the following transcript:

(begin transcript)
how-long? count to one million [for i 1 100 1 []]
   3.195 count to one million
how-long? count to one hundred thousand ten times [
   [   loop 10 [
   [  how-long? count to one hundred thousand [for i 1 10 1[]]
   [  ]
   [   ]
   0.33 count to one hundred thousand
   0.321 count to one hundred thousand
   0.31 count to one hundred thousand
   0.321 count to one hundred thousand
   0.31 count to one hundred thousand
   0.321 count to one hundred thousand
   0.32 count to one hundred thousand
   0.321 count to one hundred thousand
   0.31 count to one hundred thousand
   0.32 count to one hundred thousand
   3.184 count to one hundred thousand ten times
   
(end transcript)

If you want accumulation of times across multiple calls, just
wrap the total in a block (per the tricky approach you quoted)
or do The Right Thing and represent stateful timing accumulators
with objects:

   time-accumulator: make object! [
   message: no message?
   total: 0.0
   reset: func [][total: 0.0]
   time-this: func [to-do [block!] /local timing] [
   timing: now/time/precise
   do to-do
   timing: to-decimal now/time/precise - timing
   total: total + timing
   print [Total: total This: timing message]
   ]
   ]

which can be used as follows:

stopwatch1: make time-accumulator [message: Watch 1]
stopwatch1/time-this [for i 1 100 1 []]
   Total: 3.155 This: 3.155 Watch 1
stopwatch2: make time-accumulator [message: smaller chunks]
loop 10 [stopwatch2/time-this [for i 1 10 1 []]]
   Total: 0.32 This: 0.32 smaller chunks
   Total: 0.631 This: 0.311 smaller chunks
   Total: 0.941 This: 0.31 smaller chunks
   Total: 1.262 This: 0.321 smaller chunks
   Total: 1.582 This: 0.32 smaller chunks
   Total: 1.893 This: 0.311 smaller chunks
   Total: 2.203 This: 0.31 smaller chunks
   Total: 2.514 This: 0.311 smaller chunks
   Total: 2.834 This: 0.32 smaller chunks
   Total: 3.144 This: 0.31 smaller chunks
   

I prefer to represent stateful entities via objects rather than
functions.  Among other reasons, stateful functions depend on aspects
of REBOL (persistence of mutations to literal series values) that
are very mysterious to REBOL newbies.  There's no point in being
obscure, just for the sake of obscurity!  ;-)

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446

Counting lines of code is to software development as
counting bricks is to urban development.


-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] to/make datatype!

2002-10-16 Thread Joel Neely

Hi, all,

Some conversions to/from STRING! work nicely (and in the obvious,
intuitive fashion),

 join  1  == 1
 to-string 1== 1
 mold 1 == 1

and

 type? to-integer 1   == integer!
 type? to-decimal 1   == decimal!
 type? to integer! 1  == integer!
 type? to decimal! 1  == decimal!
 type? make integer! 1== integer!
 type? make decimal! 1== decimal!

We can convert a DATATYPE! value to a STRING! value in different
ways, with slightly different results,

 int-type: type? 1 == integer!

 join  int-type  == integer
 to-string int-type== integer
 mold int-type == integer!

(note the presence/absence of the trailing bang), but the
corresponding transformations *don't* work then other way,
with no TO-xxx shortcut:

 to-datatype int-type-name
** Script Error: to-datatype has no value
** Where: halt-view
** Near: to-datatype int-type-name

and no support from TO or MAKE either:

 to datatype! int-type-name
** Script Error: Cannot use to on datatype! value
** Where: halt-view
** Near: to datatype! int-type-name
 make datatype! int-type-name
** Script Error: Cannot use make on datatype! value
** Where: halt-view
** Near: make datatype! int-type-name

So far the most simplest way I've come up with to create a DATATYPE!
value from a STRING! value is

to-datatype: func [s [string!]] [
first reduce load rejoin [
[ s either #! = last s []] [!]]
]
]

 type? to-datatype string == datatype!
 make to-datatype integer 12== 12

There's *got* to be a better way!  Any suggestions?

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




[REBOL] Re: to/make datatype!

2002-10-16 Thread Joel Neely

Thanks, Scott!

G. Scott Jones wrote:
 
 From: Joel Neely
 ...
 
  to-datatype: func [s [string!]] [
  first reduce load rejoin [
  [ s either #! = last s []] [!]]
  ]
  ]
 
   type? to-datatype string == datatype!
   make to-datatype integer 12== 12
 
  There's *got* to be a better way!  Any suggestions?
 
...
 
 to-datatype: func [s [string!]] [
 do join s either #! = last s [][!]
 ]
 
 ;where
 type? to-datatype string  ;== datatype!
 to to-datatype string 12 ;== 12
 

That's certainly an improvement, IMHO!  Anybody know why it has to be
so hard?

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




[REBOL] Re: XML.com Embedded Markup Considered Harmful [Oct. 02,1997]

2002-10-13 Thread Joel Neely

Hi, Dick,

Two thoughts, one a direct reply and one more deferred...

[EMAIL PROTECTED] wrote:
 
 I originally chirped in on the XML comments ...
 
 Seems that there should be an XML_Display...
 
XML_Display (25 87 20) (date)
(2 2 ReshapeOf  4 Random 1000) (UCase Hello World)
 
 VECTOR LENGTH=4
 VECTOR LENGTH=3
 SCALAR DATATYPE=NUMERIC25/SCALAR
 SCALAR DATATYPE=NUMERIC87/SCALAR
 SCALAR DATATYPE=NUMERIC20/SCALAR
 /VECTOR
 STRINGSun Oct 13 07:00:24 2002/STRING
 ARRAY RANK=2 SHAPE=2,2
 SCALAR DATATYPE=NUMERIC12/SCALAR
 SCALAR DATATYPE=NUMERIC987/SCALAR
 SCALAR DATATYPE=NUMERIC82/SCALAR
 SCALAR DATATYPE=NUMERIC132/SCALAR
 /ARRAY
 STRINGHELLO WORLD/STRING
 /VECTOR
 

1)  The REBOL-to-XML issue seems simple; consider this fragment ...

8--

r2x: make object! [
buff: {}
padl: 0 
v:none
emit: func [sb [string! block!]] [
insert  
insert  
insert/dup tail buff {} padl  
either block? sb [rejoin sb] [sb]
newline 
]
render-item: func [v [any-type!] /local t] [
emit [{} t: type? v {} v {/} t {}]
]
v: none 
rule: [ 
any [   
into [  
(   
emit {block}
padl: padl + 1
)
rule
(   
padl: padl - 1
emit {/block}
)
]   
|   
set v any-type!  (render-item v)
]   
]
render: func [b [block!]] [
buff: copy {} 
padl: 0 
parse/all reduce [b] rule
buff
]
]

8--

... which behaves as follows:

 reffy: [
[[25 87 20]
[13-Oct-2002
[[ [1 3 5] [2 4 6] ]
[That's all, folks!
[]
== [
[25 87 20] 
13-Oct-2002 
[[1 3 5] [2 4 6]] 
That's all, folks!
]
 print r2x/render reffy 
block
block
integer25/integer
integer87/integer
integer20/integer
/block
date13-Oct-2002/date
block
block
integer1/integer
integer3/integer
integer5/integer
/block
block
integer2/integer
integer4/integer
integer6/integer
/block
/block
stringThat's all, folks!/string
/block

Adding length attribute/value data to the block tag is left as
an
exercise to the reader.  (Mostly because it wasn't immediately
obvious
how to do so, as SET before INTO doesn't seem to do what I expected,
and I didn't have time for another research project.  Perhaps
someone
else on the list has a clue...  ;-)


2)  Back to the discussion of arbitrary choices in representation,
it's not clear to me that the concept of inherent structure
and
representation has any meaning apart from convention.  Take the case
of a two-dimensional matrix.  FORTRAN and C store such structures in
orthogonal layouts (FORTRAN varies the left subscript most rapidly,
and C varies the right subscript most rapidly), while both REBOL and
Perl would use nested one-dimensional structures (REBOL blocks or
Perl arrays).  Even my use of language betrays me if I talk about
rows and columns of the matrix, which terms imply some sort of
typographic layout.

As another example consider a REBOL block containing student data:
e.g., an ID, a name, and a phone number for each student.  One
person
might immediately think of something like this:

[
[123 Alex Ant  #555-]
[234 Betty Bee #555-]
[345 Cliff Cricket #555-]
...
]

while another would think of this:

[
[123  234   345   ...]
[Alex Ant   Betty Bee   Cliff Cricket   ...]
[{555-}   {555-}   {555-}   ...]
]

and yet another would envision:

[
123 [Alex Ant [555 ]]
234 [Betty Bee [555 ]]
345 [Cliff Cricket [555 ]]
...
]

Clearly each of these serves *some* purposes well and others poorly;
the choice ultimately is entangled with one's intended processing
(or one's habits and assumptions).

I'm not trying to beat a dead horse here, but rather just musing
quasi-philosophically about the process by which we programmers make
our design decisions, and how many of those decisions are so deeply
unconscious that we aren't even aware that there are alternatives.

EWD told a wonderful story about giving an individualized test where
the student is presented with a problem and is expected to think
aloud while designing a solution on the board in the professor's
presence.  The problem he described involves achieving a specified
condition in a single pass across a one-dimensional array, where the
obvious solution would sweep back-and-forth multiple times.  He had
been accustomed (over many uses of 

[REBOL] Re: XML.com Embedded Markup Considered Harmful [Oct. 02,1997]

2002-10-12 Thread Joel Neely

Hi, Dick,

[EMAIL PROTECTED] wrote:
 
 You must forgive me Joel,
 

None needed!  I had typed my comments very late at night, and wanted
to be sure I hadn't rambled on so much that I'd obscured my point.

-jn-

-- 
To me, boxing is like ballet, except that there's no music, no
choreography, and the dancers hit each other.
   -- Jack Handy
joel~dot~neely~FIX~PUNCTUATION~at~fedex~dot~com
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




[REBOL] Re: idioms to reduce logic clutter ?

2002-10-12 Thread Joel Neely

Jason Cunliffe wrote:
 
 Time to factor out and simplify the mess...
 

Here are some simplification strategies:

-  use default values, which can trigger default behaviors
-  use FUNC/RETURN to manage premature exits
-  use long strings
-  avoid large in-line literals
-  avoid use-once variables
-  eliminate dead code

OBSCURENOTE
The phrase

foo: either error? [foo: expression] [defaultvalue] [foo]

ensures that FOO will either be the result of a successful
evaluation or
will be the specified default value, as in

foo: either error? try [foo: 1 / a] [0] [foo]

which will result in FOO containing zero if there's a problem,
such as
an undefined word

 a
** Script Error: a has no value
** Near: a
 foo: either error? try [foo: 1 / a] [0] [foo]
== 0

or an invalid divisor

 a: 0 
== 0
 foo: either error? try [foo: 1 / a] [0] [foo]
== 0

but will give the desired result if the TRYed expression
succeeds

 a: .5
== 0.5
 foo: either error? try [foo: 1 / a] [0] [foo]
== 2

/OBSCURENOTE

Now let's apply them in one of many possible ways.
(In-line comments followed by sketch of simplified version.)

 
 ;
 ; TEST FOR PASSWORD
 ;
 
 upass: copy 
 loginstatus: false
 
 either error? try [
 ;condition
 upass:  cgi-obj/userpass
 ][
 ;error
 if = upass  [
 print rejoin [
 {bBad login!/b}
 {no user password provided  }
 {a href=upload.html}{try again}{/a}
 {br}
 ]
 ]
 quit

It appears that QUIT really means I've finished assembling my reply
page.

The following IF expression appears to be dead code, as it follows
a QUIT inside the error branch.

 if  upass  [
 print rejoin [
{funny password provided. Please }
{a href=upload.html}{try again}{/a}
{br}
 ]
 ]

Could error on fetching password be treated identically with
missing password?

 ][
 ; ok user has submitted a name and password
 ; check to see if they match
 upass:  cgi-obj/userpass
 either = upass logindict/:uname
 [loginstatus: true]
 [loginstatus: false]

The above EITHER expression is just a round-about way of saying

  loginstatus: upass = logindict/:uname

 if not loginstatus [

... but if this is the only use, why use up a name?

 ;trouble in paradise - help them out..
 print rejoin [
 {brUsername and password do not match. brPlease }
 {a href=upload.html}{try again}{/a}
 {form method=POST action=echo-login.r enctype=multipart/form-data
 iForgot your login or need to register ? br
 Please enter your email address here: /i
 input type=text name=email_address value=/
 input type=submit value=send login by email/
 /form}
 ]
 quit
 ]
 ]
 

One approach for using the above hints would look like this:

8

blah_blah_cgi: make object! [

;; all chunks of message text go here:
;; (embedded whitespace disappears unless wrapped in
pre/pre)

;; parameterize messages with common structure

msg_retry_missing: func [what [string!]] [
rejoin [
{bBad login!/b no } what { provided.br /
 a href=upload.htmltry again/a.br /}
]
]

msg_bad_password: {brUsername and password do not match.br /
Please a href=upload.htmltry again/abr /
   form method=POST action=echo-login.r
   enctype=multipart/form-data
   iForgot your login or need to register?br /
   Please enter your email address here: /ibr /
   input type=text name=email_address value=/br /
   input type=submit value=send login by email/
   /form}

msg_blah_blah: {...}

;; process form content, return string

form_results: func [
a_user [string!] ;; form userID or default (empty string)
a_pass [string!] ;; form passwd or default (empty string)
...  ;; other form data
/local vpass ;; valid password for a_user
][
if empty? a_pass [return msg_retry_mising user password]
if empty? a_name [return msg_retry_mising user name]
if any [
empty? vpass:
either error? [vpass: logindict/:a_name] [none]
[vpass]
vpass  upass
][
return msg_bad_password
]
;;  now process validated form content, and return appropriate
results
]

run: func [] [
...
print form_results
either error? [upass: cgi-obj/userpass] [] [upass]
either error? [upass: cgi-obj/username] [] [upass]
...
...
]
]


[REBOL] Re: XML.com Embedded Markup Considered Harmful [Oct. 02,1997]

2002-10-12 Thread Joel Neely
Hi, Dick,

I guess you're using a later version of REBOL than I have...

 ? average
No information on average (word has no value)
 

;-)

My point was that we use FOR or FOREACH to process array/block
structure
precisely because both directly express iteration; for a chosen
conceptual
structure of a problem, I think that it *is* a good thing for the
data
and the algorithm to reflect compatible structures, all else equal.

-jn-

[EMAIL PROTECTED] wrote:
 
 total: 0.0
 foreach grade gradeblock [total: total + grade]
 average: total / length? gradelist
 
 than the (commonly used when the structured programming issue was
 first
 unleashed on the world) more primitive
 
 100 let t = 0
 110 let i = 1
 120 if g(i) = -1 then 160
 130 let t = t + g(i)
 l40 let i = i + 1
 150 goto 120
 160 let a = t / i
 --
 
 I prefer:
 
Average expressionwhichyieldsanarrayofdata
 

-- 
Those who make peaceful revolution impossible will make violent
revolution inevitable.
  -- John F. Kennedy
joel dot neely at fedex FIX PUNCTUATION dot com
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




[REBOL] Re: XML.com Embedded Markup Considered Harmful [Oct. 02,1997]

2002-10-11 Thread Joel Neely
Hi, Dick, Kemp, and all,

I'll be the first to agree that Ted Nelson is a very bright guy, and
a real
visionary, but sometimes visionaries overstate their case to make a
point,
or miss something that doesn't quite match their vision.

[EMAIL PROTECTED] wrote:
 
 I vote for Kemp's thoughts.
 HTML and XML are merely contrived formats (wrappers).


But, as one writer put it, When I talk to you, I gotta use words! 
If
I'm gonna send data from point A to point B, I gotta use *some*
format...

WIDR, I don't think HTML and XML belong in the same sentence.  HTML
is a
conceptual hash of:

-  a particular viewpoint of a common logical structure for text
documents,
-  a heavy overlay of other viewpoints of how to mish non-text
content into
   the overall mash, and
-  an amalgam of presentation-oriented hints which assume that the
resulting
   stew will be viewed by a human being on an arbitrarily long piece
of
   virtual scrolling paper.

OTOH, XML is a meta-language and culture that include:

-  notation(s) for allowing one to design specific
formats/representations
   for particular classes of data, and
-  a preference for representing *a* hierarchical semantic
structure, rather
   than presentation formatting.

Unfortunately, there's so much hype about XML replacing (or being
translated
into) HTML via a bunch of other Xacronyms that the distinctions
above are
candidates for endangered species of the month.  ;-)

IMHO, the interesting issue with XML is as a counterbalance to ASN-1
(Unicode
text instead of bit-level binary), so that:

-  XML is human-readable (and writable, if one is e.g. creating test
data
   or small chunks of content),
-  XML is *F*A*R* easier to encode/decode,
-  ASN-1 takes way less bandwidth.

 
  I too have a major problem with HTML and XML heirarchical structure - it's
  not the way most things work.


I never thought of as XML representing the way things work, but
just as
a flexible notation for sending a description of a thing from point
A to
point B (in space *or* time).  It's an encoding.


 
  What we are doing is cramming arbitarily-structured information into a
  predefined heirarchy. What we should be doing is assigning appropriate
  structures to the information as required by (a) the intrinsic structure of
  the content, (b) the relationship between the information and the
  application, and ((c) the structure of the application itself. All 3 are
  different and should be separable, and NONE of them are always heirarchical.
 
 

We could get into *major* philosophical wars over that paragraph! 
;-)

I suggest that the activity of programming involves at least the
following
four structures:

1)  a conceptual structure of the class of problems under
consideration,
2)  a representational (e.g. data) structure for a specific instance
of
the problem class,
3)  a textual structure (source code) for a solution to the problem,
and
4)  a dynamic structure of events that occur as a computer performs
the
solution of an instance of the problem class.

AFAIAC, all of structured programming boils down to an approach
that
pursues harmony among those four structures.  As a trivial example,
figuring
the average of a collection of grades, can be viewed as:

1)  thinking of the collection as an iteration of (occurrences of)
the
concept of grade  [the conceptual structure];
2)  choosing to represent the collection as:
2a)  a file (iteration of lines with one grade each), or
2b)  an array (positional iteration of grade data), or
...  some other iterative structure [the representational
structure];
3)  having a notation to indicate clearly and succinctly that each
individual
grade should be added into the total [the textual structure],
and
4)  expecting the computer to repeat the operation of add this
one also
for as many instances as appropriate [the dynamic structure].

As a result, I'd rather be able to write something like

total: 0.0
foreach grade gradeblock [total: total + grade]
average: total / length? gradelist

than the (commonly used when the structured programming issue was
first
unleashed on the world) more primitive

100 let t = 0
110 let i = 1
120 if g(i) = -1 then 160
130 let t = t + g(i)
l40 let i = i + 1
150 goto 120
160 let a = t / i

because the text doesn't contain any single/simple/unambiguous
thing
that indicates repetition/iteration.  Harmony among structures is A
Good
Thing IMHO.

That said, I was careful above to keep saying a ... structure
rather
than the ... structure because most non-trivial problems can be
thought
about in more than one way, and it's only to be expected that two
people
who think about a problem in different ways will develop different
structures for their representations, program text, and execution
events.

average (L) = avg (L, 0, 0).
avg ([], t, n)  = t / n.
avg ([g | r], t, n) = avg (r, t + g, n + 1)

Anytime we communicate an instance of a concept from 

[REBOL] Off-the-wall request

2002-10-09 Thread Joel Neely
 snippets that I feel
should be included in the remarks.

FOR EXTRA FUN:

If you wish to submit additional solutions in other languages (than
REBOL/Core, that is) I'd be happy to have them.  I can't promise to
have access to any other language implementations, but this is about
looking at source code anyway, so that doesn't really matter.


Thanks in advance to anyone willing to participate!

-jn-

-- 
--
Joel NeelyjoelDOTneelyATfedexDOTcom   901-263-4446
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




[REBOL] Re: if and parens

2002-10-05 Thread Joel Neely

Hi, Laurent,

Infix (operators) has higher precedence than prefix (function
evaluation), so the expression

if get in info? to-file elt 'type = 'file [print elt]

is actually treated by REBOL in the same order as if parenthesized as

if get (in (info? (to-file elt)) ('type = 'file)) [print elt]

that is, the IN is applied to the INFO? object, but the second
argument is the LOGICAL! value FALSE, which, as the error message
stated, is not a WORD! value.

Since you just want to exclude subdirectories from the list of
contents of the current directory, you could write

 foreach elt read %. [if not dir? elt [print elt]]

instead.

-jn-


Laurent Giroud wrote:
 
 Hi everyone again,
 
 I have a little problem that I encounter quite frequently with 'if
...
 
 this simply prints the list of files in the current folder and works
 quite fine :
 
  foreach elt read %. [if (get in info? to-file elt 'type) = 'file [print elt]]
...
 


-- 
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t:  foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




[REBOL] Re: radical pov ... Re: Re: rebol/base

2002-09-30 Thread Joel Neely

Hi, Petr,

Petr Krenzelok wrote:
 
 Yes, it is - but enough is enough imo. Just ask someone from
 external world, what do they know about Rebol? If they even
 recognise it, they are already confused by all the following:
 
 Rebol/Core
 [snip snip snip snip ...]
 Rebol/Encap
 
 not to mention Rebol/World, Rebol/Media, Rebol/Author,
 Rebol/Apache, etc., which appeared here or there even in some
 of announcements, articles, etc.
 
...
 
 ... My suggestion is - change Rebol architecture for good, do
 it clever way, allow options and reduce product line - remove
 /Pro and /Command versions - add real components...
 
 Sorry for bringing in different pov, maybe a radical one, but
 that's just me (and those agreeing with me, staying silent ;-)
 

This is me agreeing and being silent about it.  ;-)

Or, as John Cage put it,

I have nothing to say and I am saying it.

There's a bit of irony here, in that REBOL claims (and delivers,
for the most part) to simplify things that are complicated and
confusing in (some) other languages.  Yet many of the things
that are necessary for scaling and for marketing have ended up
appearing quite confusing.  

Simplifying the claims/versions/deliverables and exposing some
simple, common mechanisms for extensions/modules would be A
Good Thing IMHO.

-jn-
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




[REBOL] Re: Introducing REBOL/Base - FAQ

2002-09-29 Thread Joel Neely

IIRC Photon is the name of the GUI environment for QNX.

-jn-

Anton wrote:
 
 REBOL/Photon
 Anton.
 
  On Sat, 28 Sep 2002, Carl at REBOL wrote:
 
 
   Q: Does /Base include graphics functions?
  
   A: No. But, there will be a similar version of REBOL/View (as
  of yet unnamed, got any ideas?).
 
  REBOL/Squint
 
 --
 To unsubscribe from this list, please send an email to
 [EMAIL PROTECTED] with unsubscribe in the
 subject, without the quotes.

-- 
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t:  foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




[REBOL] Re: cyclic values

2002-09-29 Thread Joel Neely

Hi, Pat,

Ingeneous!!!

(...of course, with me, there's always a but... ;-)

pat665 wrote:
 
 I want to get values in order from a block, the first value
 coming again after the last, and this forever. Is there a
 better way than the one I am using now ?
 
 colors: [red green blue]
 
 ; I want color to be red, then green, then blue, then red
 ;again forever
 ; the first value is duplicated
 
 color: first colors
 append colors color
 
 ; then forever
 color: select colors color
 

That's a nice compact way to accomplish your stated result,
but under two constraints:

1)  the number of values in the block is very small, and
2)  the values are all distinct.


SMALL NUMBER OF VALUES
--

Given REBOL 1-origin indexing, the fastest/simplest way I've
found for cycling an integer counter through the range of
values 1..N is

cnt: 0 ;; initialization

cnt: cnt // N + 1

which means we could get your forever case above by using

color: pick colors cnt: cnt // + 1

The alternative to using the modulus operator is explicit
logic, as in

color: pick colors counter:
either counter  length? colors [counter + 1] [1]

but that is very sub-optimal...

In any case, the time complexity of modifying the integer
index is O(1) -- constant -- while the time complexity of
SELECT on an ordinary block is O(N) -- linear on the size
of the block.  A little quick benchmarking shows that this
adds up very quickly.  On my old slow benchmarking box
(200 MHz Pentium, w95) the timings are (in microseconds)

  SELECTmodulusEITHER...
3 elements 13.94 14.28  18.73
   10 elements 16.76 14.72  19.33

(As you can see from the second column, there's still some
statistical variability...)

The above times were taken using function evaluations, so
after removing that overhead, we get the following ratios:

 SELECT  EITHER...
   vs  vs
modulus  modulus
3 elements0.971.41
   10 elements1.181.41

With only three elements, the SELECT approach saves 3% over
the modulus approach, but the EITHER strategy costs 41% extra.
But with ten elements, SELECT is now 18% slower than modulus,
while EITHER is still 41% slower.

CONCLUSION:  The SELECT strategy doesn't scale well.


DISTINCT VALUES
---

Suppose you wanted to simulate a monitor which was cycling between
the primary colors (e.g. using your original COLORS data), but went
off in between each color (e.g. interspersed black displays).  If
we change our block to contain:

colors: [red black green black blue black]
color:  first colors

and then try

color: select colors color

We'll find that we're stuck in a green/black cycle, since the first
occurrence of black is always the one that's found by SELECT.

CONCLUSION:  The SELECT strategy doesn't handle cases with values
 that occur more than once in the block.


HOWEVER...  With all of the above said, for small blocks with
distinct values, your approach is quite elegant.  Thanks for
posting it!

-jn-

-- 
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t:  foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




[REBOL] Re: Delete an Instance of an Object

2002-09-29 Thread Joel Neely

Hi, Philippe,

Can you supply a little more detail?

Philippe Oehler wrote:
 
 How Can I delete an instance of an object ?
 

In the simple case of something like

myword: make object! [...]

you can simply evaluate

myword: none

or any other expression that destroys the reference to the
object.  However AFAIK the object isn't really eligible for
garbage collection until all references have gone away.  If
you other references, then it's not yet garbage.  For example,

foo: make object! [...]
gorp: make block! 10
loop 10 [
insert tail gorp make foo [...]
]
myword: first gorp

creates a situation in which evaluating either (one) of

myword: none

or

gorp: none

still leaves another reference to the first object created
from FOO.

Does that address your question, or am I missing something?

-jn-

-- 
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t:  foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




[REBOL] Re: cyclic values

2002-09-29 Thread Joel Neely

Hi, Carl

Carl Read wrote:
 
  ...
 
 Indeed.  But it suggests a way I haven't seen posted...
 
  colors: [red green blue]
 == [red green blue]
  forever [print color: colors/1 remove append colors color]
 red
 green
 blue
 red
 green
 blue
 red
 green
 blue
 red
 green
 blue
 red
 green
 blue
 red
 (escape)
 
 Has the advantage of no extra words being needed.  The
 disadvantages being the contents of the colors block is
 cycling, (might or might not matter), and it may be slower...
 It should have a consistant speed though.  Comments Joel?
 

Don't try this at home kids!   ;-)

Cycling the values within the block does matter; there's much
more memory management overhead.  Using the same benchmarks as
in the earlier comparison, the block-cycling version takes 4
to 5 times as long as the modulus approach for 3-10 elements.

In addition the
overhead grows with the length of the block being cycled:

bruteforce: func [n [integer!] c [integer!] /local t b v] [
b: make block! n
repeat i n [insert tail b i]
t: now/time/precise
loop c [ remove append b v: b/1 ]
t: to-decimal now/time/precise - t
]

behaves as:

 for i 10 200 10 [print [i bruteforce i 50]]
10 24.99
20 22.91
30 29.49
40 25.27
50 23.45
60 27.19
70 25.76
80 29.22
90 25.98
100 29.6
110 26.75
120 30.05
130 27.24
140 28.89
150 29.83
160 30.71
170 30.97
180 31.2
190 33.18
200 32.9

The raggedness likely indicates intermittent gc operations; the
trend is definitely upward as the block length grows.

-jn-

-- 
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t:  foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




[REBOL] Re: Byte on Mac OS X (and Rebol too)

2002-09-28 Thread Joel Neely

Hi, Gabriele and all,

I posted some links re this topic on Thursday, with subject

[REBOL] Re: Cross 'X' Platform?

I agree it's encouraging that he mentioned REBOL in the same
list with other important tools.

Gabriele Santilli wrote:
 
 Hi Paolo,
 
 On Saturday, September 28, 2002, 6:34:59 AM, you wrote:
 
 PR I just found this one on byte.com:
 PR http://www.byte.com/documents/s=7620/byt1032475416823/0923_bar.html
 
 [OT]  I  wonder  if  this  stimulates the Linux people to create a
 better  desktop,  and  better multimedia support. The only thing I
 didn't  like  was  that  BSD  kernel  running  on  top  of a Mach
 microkernel  ---  I'm  not sure I would want an OS that needs TWO
 kernels  to  run.  (Also,  that not on microkernels not being fast
 enough shows that that guy has never seen AmigaOS or QNX...)
 

I'm a bit puzzled by his choice of phrasing re kernel layers, but
don't see kernel over microkernel as any more of an issue than
layers in other contexts (e.g., protocol stacks).  The use of a
microkernel as a single point of control for resource sharing and
message passing in support of higher layers of system management
is well established AFAICT in the RTOS arena, where speed is of
the essence (pSOS in addition to your citation of QNX).  Just for
the sake of completeness, we could add the Next OS (of which OS X
appears to be a descendent).

However, the point remains that getting Unix on the desktop is A
Good Thing, and the choice of Aqua-vs-terminal as the primary point
of contact is a tomayto/tomahto issue AFAIAC.

IMHO, the combination of VisiCalc and the Apple ][ probably had more
to do with early penetration of the professional (e.g. accountants)
and corporate markets by personal computing than anything else.
Wouldn't it be great if the combination of Mac OS X (nee Unix) and
REBOL could play a corresponding role in helping the larger market
really get it about distributed computing as well?

And even if it does so by motivating the Linux community to pay
more attention to interfaces for the non-technical user, that's OK
too...  Take a look at

http://slashdot.org/articles/02/09/27/148235.shtml?tid=120

for another Unix-on-desktop alternative: a $199 box sold by WalMart
which runs Lindows (Debian deriviative with glue to run uSoft apps)
now supported by AOL.

Any foot in the door will do...  ;-)

-jn-

-- 
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t:  foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with unsubscribe in the 
subject, without the quotes.




  1   2   3   4   5   6   >