Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CAlive utility casks for arbitrary code injection as needed

114 views
Skip to first unread message

Rick C. Hodgin

unread,
Oct 29, 2015, 3:10:42 PM10/29/15
to
One issue I've always had with C is the need sometimes to initialize
pass-thru values. I thought this might be a nice way to visualize
the use of a cask.

Consider:

01: struct SAbc* abc;
02:
03: for (....)
04: {
05: abc = NULL;
06: if (some_function(&abc))
07: // Do something
08: }
09:
10: SAbc* some_function(struct SAbc** abcp)
11: {
12: if (some_condition)
13: *abcp = &some_other_abc_var;
14:
15: return(*abcp);
16: }

In this case, the value of abc on line 06, it must be initialized on
line 05 before it can be used in this context because if it is not
initialized, it may contain a value from the prior iteration.

Rather than initialize the value on line 05, that code could be changed
into this, allowing the initialization to occur where it's needed:

01: struct SAbc* abc;
02:
03: for (....)
04: {
05:
06: if (some_function( ~|abc=NULL;|~ &abc))
07: // Do something
08: }
09:

In this context, the ~|utility|~ cask allows the arbitrary injection
of code into the otherwise syntactically correct statement. It
initializes abc to NULL at the point of use, helping also to document
why that operation takes place. And in a future vision, the entire
code surrounding that parameter can be logically extracted and placed
into a conceptual cask, one which would appear in source code like
this:

05: +------------+
06: if (some_function(|| abc=NULL; ||))
07: // Do somethin|| &abc ||
08: } +------------+
09:

Showing a type of graphical popup which visualizes all of the source
code which is associated with input into that parameter, allowing
the more traditional form as by the original line 05 up above to also
remain within the cask, but only within the view provided for by the
editor. In source code, it is brought in to where it is used, which
conveys more closely the reason why it's needed at that point.

And, of course, with multiple similar parameters, they can all be
updated likewise, with each of them having their own parameter popup
window, showing the multi-line code which feeds into each parameter
as it's used.

-----
In a GUI editor it would be showing graphically what a utility cask
looks like, and it would appear visual. In this text-based form I
have inserted extra spaces to make it stand out. However, it could
actually appear like this in source code without any extra spaces:

05: if (some_function(~|abc=NULL;|~&abc))

But without the syntax highlighting, it is confusing to the eye,
even to my eye which is beginning to recognize casks. With syntax
highlighting it would look something like this:

In the upper-right editor window
http://www.visual-freepro.org/images/vjr_047.png

Here you see (|reference|) casks for (|width|) and (|height|)
http://www.visual-freepro.org/images/vjr_053.png

Those are in VXB, which is an XBASE language. However, they will
be identical in CAlive. You can see their definition here beginning
around line 110:

https://github.com/RickCHodgin/libsf/blob/master/exodus/tools/rdc/rdc_specs.txt

And I am working on getting my book completed here:

https://github.com/RickCHodgin/libsf/blob/master/books/rdc/rdc.odt

Best regards,
Rick C. Hodgin

Ben Bacarisse

unread,
Oct 29, 2015, 4:05:15 PM10/29/15
to
Alternatively (and more topically) you could use standard C:

> 01: struct SAbc* abc;
> 02:
> 03: for (....)
> 04: {
> 05:
> 06: if (some_function( ~|abc=NULL;|~ &abc))

if (some_function( (abc = NULL, &abc) ))

or, if the value of abc does not need to be retained:

if (some_function( &(struct abc *){NULL} ))

> 07: // Do something
> 08: }

These many not be equivalent (you've never fully defined what a "cask"
is) but the first fits the description given here, and the second works
with the scant code outline you gave.

Much better would be to post an actual code sample, a real algorithm
that's got you bothered about how to write it in C, and people here can
then help with ideas on how they would do it. (Such threads are often
very informative.)

<snip>
--
Ben.

Barry Schwarz

unread,
Oct 29, 2015, 5:36:21 PM10/29/15
to
The value of abc is not passed to some_function. Only its address is
passed. Since some_function does not attempt to evaluate the value
pointed to by abcp, there is no need to initialize abc prior to the
call.

Even if abc contained a value from a prior iteration, some_function
changes that value without regard to the previous value.


--
Remove del for email

Bartc

unread,
Oct 29, 2015, 5:48:26 PM10/29/15
to
On 29/10/2015 19:10, Rick C. Hodgin wrote:

> 03: for (....)
> 04: {
> 05: abc = NULL;
> 06: if (some_function(&abc))
> 07: // Do something
> 08: }

> 03: for (....)
> 04: {
> 05:
> 06: if (some_function( ~|abc=NULL;|~ &abc))
> 07: // Do something
> 08: }
> 09:

The first example is a lot easier to understand than the second. And
it's simpler (I assume they do the same thing. If not, then that's
another problem.)

(It helps sometimes if you imagine yourself trying to dictate code over
the phone. The second example would tie you both up in knots.)

IMO.

If you want to sell the idea of 'casks', you need a better example I think.

Does ~|....|~ denote a bit of code that is not immediately evaluated
(maybe like QUOTE in Lisp)? If so, then perhaps {...} (used in an
expression context) might be better, although it's still not clear how
it would be used.

--
Bartc


asetof...@gmail.com

unread,
Oct 29, 2015, 5:55:54 PM10/29/15
to
Barry Schwarz wrote:
The value of abc is not passed to some_function. Only its address is
passed. Since some_function does not attempt to evaluate the value
pointed to by abcp, there is no need to initialize abc prior to the
call.

Even if abc contained a value from a prior iteration, some_function
changes that value without regard to the previous value.
------
I agree; for me initialization
for the pointer has to be inside
the function: Example
u32 *p;

f(&p, args)

Where
i32 f(u32** pp, args)
{...
if(pp==0) return -1;
*pp=0;

}

Rick C. Hodgin

unread,
Oct 29, 2015, 6:47:10 PM10/29/15
to
In this example, the called function assigns a pointer to the pointer-
to-pointer passed by &abc.

> Even if abc contained a value from a prior iteration, some_function
> changes that value without regard to the previous value.

some_function() doesn't always update the value. If it didn't update
it, the pass-thru NULL value would be desired.

Rick C. Hodgin

unread,
Oct 29, 2015, 7:01:10 PM10/29/15
to
On Thursday, October 29, 2015 at 5:48:26 PM UTC-4, Bart wrote:
> Does ~|....|~ denote a bit of code that is not immediately evaluated
> (maybe like QUOTE in Lisp)?

The ~|utility|~ cask is an arbitrary injection of any code. It will
be inserted at whatever point you insert the cask in a statement.
The contents of the utility can contain anything. If it is a larger
block it will be filled with multi-line content between the ~| and |~
sides. However, CAlive provides for another feature whenever larger
bits of code are required. They would typically be used, along with
the (|reference|) casks, instead of the ~|utility|~ cask:

// adhocs are basically local functions, but they are defined
// near where they're used to remove some complex logic for use
// of a placeholder.
adhoc somename
{
// Complex/larger code goes here
}

example( (|somename|) ...);

// adhoc functions can also be called as normal functions:
somename();

// Or as stand-alone casks:
(|somename|);

With casks, you can inject the code at any point in the flow.

To pass a parameter, use the (|reference|param||) syntax. To return
a value, use the (||return|reference|) syntax. To use both use the
(||return|reference|param||) syntax. These have the equivalents of
reference(param);, return = reference();, and return = reference(param);
operations.

And, they can be dropped in at any point in code:

adhoc value(int x)
{
printf("%d\n", x);
}

printf("%d\n", (|value|x||) some_function(&x) (|value|x||) );

In this case, (|value|) is called twice with the value x. In this
case, x is updated by the some_function() call, so the cask on the
left is called before some_function(&x); is called, and the cask on
the right is called after x is updated, showing two potentially
different values and all of this happens before the outer printf()
is called.

It's just a way to inject arbitrary code at any location, allowing
for parameters to be passed, and return values to be received.

> If so, then perhaps {...} (used in an
> expression context) might be better, although it's still not clear how
> it would be used.

Barry Schwarz

unread,
Oct 29, 2015, 9:17:53 PM10/29/15
to
On Thu, 29 Oct 2015 15:46:55 -0700 (PDT), "Rick C. Hodgin"
I don't see that. The called function stores a value in the object
pointed to by abcp. That object is abc. abc is a pointer, not a
pointer-to-pointer.

But I see now that if some_condition is false, the function will
return the value of abc and therefore it needs to be
initialized/assigned prior to the function call.

Ian Collins

unread,
Oct 29, 2015, 9:25:39 PM10/29/15
to
Rick C. Hodgin wrote:
> On Thursday, October 29, 2015 at 5:48:26 PM UTC-4, Bart wrote:
>> Does ~|....|~ denote a bit of code that is not immediately evaluated
>> (maybe like QUOTE in Lisp)?
>
> The ~|utility|~ cask is an arbitrary injection of any code. It will
> be inserted at whatever point you insert the cask in a statement.
> The contents of the utility can contain anything. If it is a larger
> block it will be filled with multi-line content between the ~| and |~
> sides. However, CAlive provides for another feature whenever larger
> bits of code are required. They would typically be used, along with
> the (|reference|) casks, instead of the ~|utility|~ cask:

If I remember correctly, the last time this topic came up it was
demonstrated that C++ cam already do what you were after.

You should broaden your knowledge of other languages before trying to
reinvent wheels.

--
Ian Collins

Bartc

unread,
Oct 29, 2015, 9:32:51 PM10/29/15
to
On 29/10/2015 23:00, Rick C. Hodgin wrote:
> On Thursday, October 29, 2015 at 5:48:26 PM UTC-4, Bart wrote:
>> Does ~|....|~ denote a bit of code that is not immediately evaluated
>> (maybe like QUOTE in Lisp)?
>

> And, they can be dropped in at any point in code:
>
> adhoc value(int x)
> {
> printf("%d\n", x);
> }
>
> printf("%d\n", (|value|x||) some_function(&x) (|value|x||) );

gcc has an extension which allows you to write this:

printf("%d\n", ({value(x); some_function(&x); value(x);}));

The ({....}) syntax allows any set of statements wherever an expression
normally goes.

And standard C obviously allows this:

printf("%d\n", (value(x), some_function(&x), value(x)));

With both of these, the value passed to this printf (not the one in
value()), is the result of the second value(), although your example
doesn't have a return value.

But with your version using 'casks', it is by no means clear what the
value of the sequence is either. Is it the result of calling
some_function() that is passed to printf(), and the (|value|x||) is
executed after?

So the sequence is:

call value(x)
call some_function(&x) and push that value for the printf
call value(x) again, before calling printf (and before any
subsequent arguments for printf)?

If so, then normal C can emulate that using:

printf("%d\n", (value(x), temp=some_function(&x), value(x), temp));

where at least it more obvious what is happening as all constructs are
standard.

Oh, and gcc also has local functions.

--
Bartc

Rick C. Hodgin

unread,
Oct 29, 2015, 9:42:20 PM10/29/15
to
On Thursday, October 29, 2015 at 9:25:39 PM UTC-4, Ian Collins wrote:
> Rick C. Hodgin wrote:
> > On Thursday, October 29, 2015 at 5:48:26 PM UTC-4, Bart wrote:
> >> Does ~|....|~ denote a bit of code that is not immediately evaluated
> >> (maybe like QUOTE in Lisp)?
> >
> > The ~|utility|~ cask is an arbitrary injection of any code. It will
> > be inserted at whatever point you insert the cask in a statement.
> > The contents of the utility can contain anything. If it is a larger
> > block it will be filled with multi-line content between the ~| and |~
> > sides. However, CAlive provides for another feature whenever larger
> > bits of code are required. They would typically be used, along with
> > the (|reference|) casks, instead of the ~|utility|~ cask:
>
> If I remember correctly, the last time this topic came up it was
> demonstrated that C++ cam already do what you were after.

And as I told you back then, and you refused to listen to it, C++
cannot do what casks do. Nor a dozen other things I propose in
my language.

> You should broaden your knowledge of other languages before trying to
> reinvent wheels.

Rick C. Hodgin

unread,
Oct 29, 2015, 10:00:20 PM10/29/15
to
On Thursday, October 29, 2015 at 9:32:51 PM UTC-4, Bart wrote:
> On 29/10/2015 23:00, Rick C. Hodgin wrote:
> > On Thursday, October 29, 2015 at 5:48:26 PM UTC-4, Bart wrote:
> >> Does ~|....|~ denote a bit of code that is not immediately evaluated
> >> (maybe like QUOTE in Lisp)?
> >
>
> > And, they can be dropped in at any point in code:
> >
> > adhoc value(int x)
> > {
> > printf("%d\n", x);
> > }
> >
> > printf("%d\n", (|value|x||) some_function(&x) (|value|x||) );
>
> gcc has an extension which allows you to write this:
>
> printf("%d\n", ({value(x); some_function(&x); value(x);}));
>
> The ({....}) syntax allows any set of statements wherever an expression
> normally goes.
>
> And standard C obviously allows this:
>
> printf("%d\n", (value(x), some_function(&x), value(x)));
>
> With both of these, the value passed to this printf (not the one in
> value()), is the result of the second value(), although your example
> doesn't have a return value.
>
> But with your version using 'casks', it is by no means clear what the
> value of the sequence is either. Is it the result of calling
> some_function() that is passed to printf(), and the (|value|x||) is
> executed after?

It is left-to-right, and the return value of casks do not affect
any other results unless they are used as singletons, or in other
casks, even if they have return results. In all cases where they
are injected into other code, unless they are the only parameter,
their return values are silently ignored.

> So the sequence is:
>
> call value(x)
> call some_function(&x) and push that value for the printf
> call value(x) again, before calling printf (and before any
> subsequent arguments for printf)?
>
> If so, then normal C can emulate that using:
>
> printf("%d\n", (value(x), temp=some_function(&x), value(x), temp));
>
> where at least it more obvious what is happening as all constructs are
> standard.

Yup. A developer could code that if s/he wanted to.

> Oh, and gcc also has local functions.

Not all C compilers support this. And only gcc supports this, not g++.
CAlive has in its design support the basic class, and these features.

Philip Lantz

unread,
Oct 30, 2015, 12:51:28 AM10/30/15
to
Rick C. Hodgin wrote:
>
> On Thursday, October 29, 2015 at 9:25:39 PM UTC-4, Ian Collins wrote:
> > Rick C. Hodgin wrote:
> > > On Thursday, October 29, 2015 at 5:48:26 PM UTC-4, Bart wrote:
> > >> Does ~|....|~ denote a bit of code that is not immediately evaluated
> > >> (maybe like QUOTE in Lisp)?
> > >
> > > The ~|utility|~ cask is an arbitrary injection of any code. It will
> > > be inserted at whatever point you insert the cask in a statement.
> > > The contents of the utility can contain anything. If it is a larger
> > > block it will be filled with multi-line content between the ~| and |~
> > > sides. However, CAlive provides for another feature whenever larger
> > > bits of code are required. They would typically be used, along with
> > > the (|reference|) casks, instead of the ~|utility|~ cask:
> >
> > If I remember correctly, the last time this topic came up it was
> > demonstrated that C++ cam already do what you were after.
>
> And as I told you back then, and you refused to listen to it, C++
> cannot do what casks do. Nor a dozen other things I propose in
> my language.

Perhaps, but it *can* do everything you have shown in your examples. If
you want to show casks' utility, you might wish to expand your examples
to show things that C++ cannot do.

Philip Lantz

unread,
Oct 30, 2015, 12:55:48 AM10/30/15
to
Rick C. Hodgin wrote:
> Bart wrote:
> > Oh, and gcc also has local functions.
>
> Not all C compilers support this. And only gcc supports this, not
> g++.

Standard C++ has local functions, called lambdas, which would be a good
fit to implement some of the cask examples you've shown in this thread.

Philip Lantz

unread,
Oct 30, 2015, 1:00:55 AM10/30/15
to
Rick C. Hodgin wrote:
>
> One issue I've always had with C is the need sometimes to initialize
> pass-thru values. I thought this might be a nice way to visualize
> the use of a cask.
> [snip description and examples]

I'm curious about the name "cask". What is its derivation, or is it
simply a made-up word? If the former, understanding the derivation might
help me grok the capability. If it's the latter, I wonder if it wouldn't
be better to use a word that doesn't sound and look so similar to the
name of an existing C feature.

Ian Collins

unread,
Oct 30, 2015, 3:34:25 AM10/30/15
to
Rick C. Hodgin wrote:
> On Thursday, October 29, 2015 at 9:25:39 PM UTC-4, Ian Collins wrote:
>> Rick C. Hodgin wrote:
>>> On Thursday, October 29, 2015 at 5:48:26 PM UTC-4, Bart wrote:
>>>> Does ~|....|~ denote a bit of code that is not immediately evaluated
>>>> (maybe like QUOTE in Lisp)?
>>>
>>> The ~|utility|~ cask is an arbitrary injection of any code. It will
>>> be inserted at whatever point you insert the cask in a statement.
>>> The contents of the utility can contain anything. If it is a larger
>>> block it will be filled with multi-line content between the ~| and |~
>>> sides. However, CAlive provides for another feature whenever larger
>>> bits of code are required. They would typically be used, along with
>>> the (|reference|) casks, instead of the ~|utility|~ cask:
>>
>> If I remember correctly, the last time this topic came up it was
>> demonstrated that C++ cam already do what you were after.
>
> And as I told you back then, and you refused to listen to it, C++
> cannot do what casks do. Nor a dozen other things I propose in
> my language.

So provide an example use that C++ can't match. If you are attempting
to prove the utility of a new idea, you have to show that is is new.

--
Ian Collins

Malcolm McLean

unread,
Oct 30, 2015, 5:09:46 AM10/30/15
to
On Friday, October 30, 2015 at 7:34:25 AM UTC, Ian Collins wrote:
>
> So provide an example use that C++ can't match. If you are attempting
> to prove the utility of a new idea, you have to show that is is new.
>
"Power" is rather an elusive idea.
It's presumably possible to write an interpreter for CAlive in C++,
there's nothing it can do that C++ totally can't.
However a cask looks a bit like a lambda function to me. The utility
isn't immediately obvious, but actually thought is moving in that
direction.

David Brown

unread,
Oct 30, 2015, 6:12:42 AM10/30/15
to
I think Rick's "adhoc" functions are basically lambdas, or perhaps
simply nested functions (a gcc extension, and legal in many other
programming languages). There is always a bit of detail when talking
about such functions (how do you access local data in the surrounding
scope, how and when are variables captured, and so on) - but the
principle is there.

I /think/ casks could also be handled by making and then calling a
lambda function at the same point:

for (...)
{
if (some_function(~| abc = NULL; |~ &abc))
// Do something
}

is the same as (if I've got the syntax correct):

for (...)
{
if (some_function([&]{ abc = NULL;}(), &abc))
// Do something
}

I much prefer the simpler, clearer version:

for (...)
{
struct SAbc* abc = NULL;
if (some_function(&abc))
// Do something
}


So I too am waiting for an example of casks that a) /really/ improve the
code, and b) cannot be done just as well (and just as clearly) using C++
(or perhaps even standard C, or with compiler-specific extensions).

But I'm glad to see Rick is trying to answer this challenge.

Ben Bacarisse

unread,
Oct 30, 2015, 6:55:24 AM10/30/15
to
"Rick C. Hodgin" <rick.c...@gmail.com> writes:

> On Thursday, October 29, 2015 at 9:32:51 PM UTC-4, Bart wrote:
<snip>
>> The ({....}) syntax allows any set of statements wherever an expression
>> normally goes.
<snip>
>> Oh, and gcc also has local functions.
>
> Not all C compilers support this. And only gcc supports this, not g++.
> CAlive has in its design support the basic class, and these features.

That's an odd argument to use. As I understand it, zero compilers
support CAlive and if there ever is one, it will target a far narrower
range of hardware then gcc does. The argument for a new language must
always be from utility, not ubiquity.

--
Ben.

Rick C. Hodgin

unread,
Oct 30, 2015, 7:01:31 AM10/30/15
to
Its name derived from the graphical appearance of the (|cask|) in my
early (mid-1990s) vision for this feature. With the various pipe
sign characters, it looked like a cask turned over on its side:

https://pbs.twimg.com/profile_images/613435389513216000/yAzTSy1o.jpg

There are four types of casks in all:

(|reference|) -- accesses something that exists
[|definition|] -- defines something permanent from the return value
<|logic|> -- used near logic to run code based on true/false
~|utility|~ -- arbitrary code injection

All casks are sealed quantities which exist as a cask placeholder in
the GUI editor. They are only expanded when they need to be.

Rick C. Hodgin

unread,
Oct 30, 2015, 7:24:57 AM10/30/15
to
You will see in time. My goals in these posts are to "warm up the
audience" by introducing little bits to chew on over time.

-----
In addition to the (|reference|) and ~|utility|~ casks, I also introduce
the logic cask.

I define two basic types:

<|meta|> called when the result is true
<|mefa|> called when the result is false

As an example of a <|logic|> cask:

adhoc iftrue { printf("true\n"); }
adhoc iffalse { printf("false\n"); }

if (x == 2 <||meta|iftrue|> <||mefa|iffalse|>)
{
// Code goes here
}

switch (x)
{
case 2 <||meta|iftrue|> <||mefa|iffalse|>:
// Code goes here
break;
}

Bear in mind that in the GUI editor, these expressions would be
reduced down to visual forms which look like this until expanded:

if (x == 2 <|iftrue|> <|iffalse|>)
{
// Code goes here
}

switch (x)
{
case 2 <|iftrue|> <|iffalse|>:
// Code goes here
break;
}

And only when some GUI interaction takes place would they be expanded.
It makes them easy to see, easy to manage. They can be grabbed hold
of with the mouse as a single unit and dragged around, etc.

-----
CAlive also introduces the "always_before" and "always_after" code blocks
for various things:

// Note: the [once] syntax below indicates "once" is a keyword that
// is optional, same for [per_call].
while (some_condition)
{
// Code goes here

} always_before [once] [per_call] {
// Code executes before the while loop begins
// If once is applied, then it only executes the first time
// the while loop is traversed throughout the lifetime of
// the program. If per_call is applied, then it will use
// a local flag to determine if it should be called.

} always_after [once] [per_call] {
// Code executes after the while loop exits
// If once is applied, then it only executes the first time
// the while loop is traversed throughout the lifetime of
// the program. If per_call is applied, then it will use
// a local flag to determine if it should be called.
}

-----
CAlive also introduces the "unless" clause:

do {
// Code goes here

} unless (some_test1) {
// Code here will execute upon entry into the block if some_test1
// fails. It can issue a break; or a retry; after setting up the
// runtime environment to try again

break;

} unless (some_test2) {
// More tests can be made

retry [all]; // If all is specified, it retries every test,
// otherwise, it retries only this test and
// then continues on to the next (if any).

} while (some_condition);
// And similarly, always_before and always_after blocks can be added.

In all of the above cases, the code that is inserted in this way so that
it's encapsulated in the place it's used, helping to create self-
documenting code. Things that relate to each other relate to each other
spatially, and not just conceptually. They also convey more of the
meaning inherent in code.

-----
CAlive also allows do loops to have their test clause at the top:

do while {
// Code goes here

// } unless (test) { blocks can go here

}; // semicolon here is optional, and ignored

Ben Bacarisse

unread,
Oct 30, 2015, 8:03:15 AM10/30/15
to
David Brown <david...@hesbynett.no> writes:
<snip>
> I think Rick's "adhoc" functions are basically lambdas, or perhaps
> simply nested functions (a gcc extension, and legal in many other
> programming languages). There is always a bit of detail when talking
> about such functions (how do you access local data in the surrounding
> scope, how and when are variables captured, and so on) - but the
> principle is there.

Rick has stated that he does not want to learn about programming
languages so he is bound to keep reinventing things, and coming up
non-standard names for them.

> I /think/ casks could also be handled by making and then calling a
> lambda function at the same point:
>
> for (...)
> {
> if (some_function(~| abc = NULL; |~ &abc))
> // Do something
> }
>
> is the same as (if I've got the syntax correct):
>
> for (...)
> {
> if (some_function([&]{ abc = NULL;}(), &abc))

You need ()s round the comma expression. But since abc is in scope
where the lambda is called, it serves no purpose. It can play a
syntactic role in this situation -- by allowing declarations and a block
of statements for example -- but that's all. But when that's what you
are doing, gcc's ({...}) is clearer.

> // Do something
> }

But in this case it's also the same as a comma expression with an
assignment. Rick needs to take more care pricking examples. A feature
needs be illustrated with an example that needs it.

<snip>
--
Ben.

David Brown

unread,
Oct 30, 2015, 8:04:31 AM10/30/15
to
On 30/10/15 12:24, Rick C. Hodgin wrote:
> On Friday, October 30, 2015 at 3:34:25 AM UTC-4, Ian Collins wrote:
>> Rick C. Hodgin wrote:
>>> On Thursday, October 29, 2015 at 9:25:39 PM UTC-4, Ian Collins wrote:
>>>> Rick C. Hodgin wrote:
>>>>> On Thursday, October 29, 2015 at 5:48:26 PM UTC-4, Bart wrote:
>>>>>> Does ~|....|~ denote a bit of code that is not immediately evaluated
>>>>>> (maybe like QUOTE in Lisp)?
>>>>>
>>>>> The ~|utility|~ cask is an arbitrary injection of any code. It will
>>>>> be inserted at whatever point you insert the cask in a statement.
>>>>> The contents of the utility can contain anything. If it is a larger
>>>>> block it will be filled with multi-line content between the ~| and |~
>>>>> sides. However, CAlive provides for another feature whenever larger
>>>>> bits of code are required. They would typically be used, along with
>>>>> the (|reference|) casks, instead of the ~|utility|~ cask:
>>>>
>>>> If I remember correctly, the last time this topic came up it was
>>>> demonstrated that C++ cam already do what you were after.
>>>
>>> And as I told you back then, and you refused to listen to it, C++
>>> cannot do what casks do. Nor a dozen other things I propose in
>>> my language.
>>
>> So provide an example use that C++ can't match. If you are attempting
>> to prove the utility of a new idea, you have to show that is is new.
>
> You will see in time. My goals in these posts are to "warm up the
> audience" by introducing little bits to chew on over time.


I can see that point, but I think if you don't come up with something
interesting soon your audience will wander away and not bother paying
attention later. I keep hoping you'll come up with something new and
interesting, or some example in which the casks give code that is
clearer, simpler, easier to maintain, or in some other way better than
could be done with existing solutions (C, C++, or extensions in existing
compilers such as gcc, clang or lcc). So far I have been disappointed -
but I haven't yet wandered away.

(Note that although your casks and adhocs can - as far as I have seen -
be replaced by standard C or C++, I strongly disapprove of writing code
in that style. The implementations using lambdas or macros are merely
to show that you don't need to invent casks in order to write bad code.)

>
> -----
> In addition to the (|reference|) and ~|utility|~ casks, I also introduce
> the logic cask.
>
> I define two basic types:
>
> <|meta|> called when the result is true
> <|mefa|> called when the result is false
>
> As an example of a <|logic|> cask:
>
> adhoc iftrue { printf("true\n"); }
> adhoc iffalse { printf("false\n"); }
>

Normal functions, macros, nested functions and lambdas are all
alternative ways to define these "adhoc" functions, though in this
example it is hard to see why you want them to be within the function
rather than file-level statics, but not simply written directly at the
place they are called.

Still, macros are the nearest plain C alternative:

#define iftrue printf("true\n")
#define iffalse printf("false\n")

> if (x == 2 <||meta|iftrue|> <||mefa|iffalse|>)
> {
> // Code goes here
> }

if (x == 2) {
iftrue;
// Code goes here
} else {
iffalse;
}


Clear, simple, and obvious. Your casks add nothing.

>
> switch (x)
> {
> case 2 <||meta|iftrue|> <||mefa|iffalse|>:
> // Code goes here
> break;
> }

The "iftrue" part can go directly in the case, just before "Code goes
here". Again, the standard C is clearer and simpler than the casks.

The "iffalse" part is harder - it is far from clear how it should
interact with other code. Should it be run for all cases other than 2?
Should it be run before or after "iftrue" parts for other cases?
Should that depend on whether those cases are before or after case 2?

Even if you have a single answer to that question, it is not going to be
obvious when used - and it will be a total mess if there are many such
clauses. It means that the actions taken in one case depend on the code
written in a different case - making the code confusing, and losing all
track of code flow. And as well as being extremely difficult for the
programmer to comprehend, it will hinder the compiler's abilities to
generate good object code.

I would need to see a /very/ convincing real-life example before this
would make sense to me.

>
> Bear in mind that in the GUI editor, these expressions would be
> reduced down to visual forms which look like this until expanded:
>
> if (x == 2 <|iftrue|> <|iffalse|>)
> {
> // Code goes here
> }
>
> switch (x)
> {
> case 2 <|iftrue|> <|iffalse|>:
> // Code goes here
> break;
> }
>
> And only when some GUI interaction takes place would they be expanded.
> It makes them easy to see, easy to manage. They can be grabbed hold
> of with the mouse as a single unit and dragged around, etc.
>

Judging from your screenshots, all I see is that these casks will have
syntax highlighting to make them a little more obvious. That does not
change how unnecessary and confusing they are.

> -----
> CAlive also introduces the "always_before" and "always_after" code blocks
> for various things:
>
> // Note: the [once] syntax below indicates "once" is a keyword that
> // is optional, same for [per_call].
> while (some_condition)
> {
> // Code goes here
>
> } always_before [once] [per_call] {
> // Code executes before the while loop begins
> // If once is applied, then it only executes the first time
> // the while loop is traversed throughout the lifetime of
> // the program. If per_call is applied, then it will use
> // a local flag to determine if it should be called.
>
> } always_after [once] [per_call] {
> // Code executes after the while loop exits
> // If once is applied, then it only executes the first time
> // the while loop is traversed throughout the lifetime of
> // the program. If per_call is applied, then it will use
> // a local flag to determine if it should be called.
> }

Why not just write the code before the while loop, after it, or inside
it as appropriate?

Your ideas read like a recipe for meringues:

1. Put 4 egg whites in a bowl.
2. Add 100g of sugar.
3. Beat the eggs before adding the sugar.
4. Bake the meringues for 1.5 hours.
5. The sugar should have been added a spoonful at a time.

I cannot fathom why you think this is a good idea.

>
> -----
> CAlive also introduces the "unless" clause:
>
> do {
> // Code goes here
>
> } unless (some_test1) {
> // Code here will execute upon entry into the block if some_test1
> // fails. It can issue a break; or a retry; after setting up the
> // runtime environment to try again
>
> break;
>
> } unless (some_test2) {
> // More tests can be made
>
> retry [all]; // If all is specified, it retries every test,
> // otherwise, it retries only this test and
> // then continues on to the next (if any).
>
> } while (some_condition);
> // And similarly, always_before and always_after blocks can be added.
>
> In all of the above cases, the code that is inserted in this way so that
> it's encapsulated in the place it's used, helping to create self-
> documenting code. Things that relate to each other relate to each other
> spatially, and not just conceptually. They also convey more of the
> meaning inherent in code.
>

The only meaning it conveys, as far as I can see here, is that the
author of the code can't think in a straight line but leaps back and
forth - and expects the compiler, the computer, and anyone reading the
code to follow the same leaps.

Again, it's going to take a /serious/ example to show any point here.

And then you have to convince us that it is better than normal C or C++,
possibly using exceptions or goto.


> -----
> CAlive also allows do loops to have their test clause at the top:
>
> do while {
> // Code goes here
>
> // } unless (test) { blocks can go here
>
> }; // semicolon here is optional, and ignored
>
>

In C, you have:

while (x) {...};

and

do {...} while (x);

Put the condition where it makes sense.

Kenny McCormack

unread,
Oct 30, 2015, 9:08:13 AM10/30/15
to
In article <MPG.309c972...@news.eternal-september.org>,
What does C++ have to do with anything??? Have you checked which newsgroup
you are posting in?

As people in this newsgroup so charmingly always put it, that comp.lang.c++
thing is down the hall, left at the water cooler, 3 doors down on your
right.

Or something like that...

--
(This discussion group is about C, ...)

Wrong. It is only OCCASIONALLY a discussion group
about C; mostly, like most "discussion" groups, it is
off-topic Rorsharch [sic] revelations of the childhood
traumas of the participants...

Kenny McCormack

unread,
Oct 30, 2015, 9:10:40 AM10/30/15
to
In article <MPG.309c982...@news.eternal-september.org>,
What does C++ have to do with anything???

--
The problem in US politics today is that it is no longer a Right/Left
thing, or a Conservative/Liberal thing, or even a Republican/Democrat
thing, but rather an Insane/not-Insane thing.

(And no, there's no way you can spin this into any confusion about
who's who...)

Kenny McCormack

unread,
Oct 30, 2015, 9:16:13 AM10/30/15
to
In article <871tccf...@bsb.me.uk>,
Ben Bacarisse <ben.u...@bsb.me.uk> wrote:
...
>Rick needs to take more care pricking examples.

Nice typo.

--
"Every time Mitt opens his mouth, a swing state gets its wings."

(Should be on a bumper sticker)

Rick C. Hodgin

unread,
Oct 30, 2015, 9:18:13 AM10/30/15
to
That's fine with me. The people who will remain are the people who
will remain. It's similar to the discussion over in comp.arch, that
those who come to Jesus do so because they have a calling on the
inside.

Those who will use CAlive will see the value I see in the offering,
and come to it for similar reasons.
adhoc touched
|params char* p
{
printf("Touched %s\n", p);
}

if ( x == 2 (|touched|"x"||) <||meta|iftrue|x||> <||mefa|iffalse|x||>
|| y == 1 (|touched|"y"||)
|| z == 3 (|touched|"z"||) <||meta|iftrue|z||> <||mefa|iffalse|z||>)
{
// Code goes here

} else {
// Code goes here
}

In each test, because the casks are inserted after the test, the
execution of the (|touched|) cask indicates it made it that far
through the || expression, and the result of each logic state
will have triggered the appropriate iftrue() and iffalse() calls.

And casks can be inserted anywhere employing similar abilities.

> > switch (x)
> > {
> > case 2 <||meta|iftrue|> <||mefa|iffalse|>:
> > // Code goes here
> > break;
> > }
>
> The "iftrue" part can go directly in the case, just before "Code goes
> here". Again, the standard C is clearer and simpler than the casks.
>
> The "iffalse" part is harder - it is far from clear how it should
> interact with other code. Should it be run for all cases other than 2?

It would be fired in all cases top-down in the case statements until
one which matches is found.

CAlive also allows for non-const values in switch statements, as well
as ranges of values (which I believe are also GCC extensions).

> Should it be run before or after "iftrue" parts for other cases?
> Should that depend on whether those cases are before or after case 2?
>
> Even if you have a single answer to that question, it is not going to be
> obvious when used - and it will be a total mess if there are many such
> clauses. It means that the actions taken in one case depend on the code
> written in a different case - making the code confusing, and losing all
> track of code flow. And as well as being extremely difficult for the
> programmer to comprehend, it will hinder the compiler's abilities to
> generate good object code.
>
> I would need to see a /very/ convincing real-life example before this
> would make sense to me.

There will be one at some point. CAlive is still a ways away from
me bringing it into a tool you can download and test. I'm doing all
of this development in my after-work hours, on weekends, and on
holidays.

> > Bear in mind that in the GUI editor, these expressions would be
> > reduced down to visual forms which look like this until expanded:
> >
> > if (x == 2 <|iftrue|> <|iffalse|>)
> > {
> > // Code goes here
> > }
> >
> > switch (x)
> > {
> > case 2 <|iftrue|> <|iffalse|>:
> > // Code goes here
> > break;
> > }
> >
> > And only when some GUI interaction takes place would they be expanded.
> > It makes them easy to see, easy to manage. They can be grabbed hold
> > of with the mouse as a single unit and dragged around, etc.
>
> Judging from your screenshots, all I see is that these casks will have
> syntax highlighting to make them a little more obvious. That does not
> change how unnecessary and confusing they are.

I have offline drawings I've made over time as I've created little
examples to introduce things.

Casks can also have what I call pips:

(|o|name|o|)

And they can have more than one pip:

(|ooo|name|oo|)

And pips can be opened or closed:

(|Ooo|name|OO")
// "O" means "open", and "o" means closed
// Why "open" and "closed"? Read on...

The original purpose I came up with back in the mid-1990s was to employ
pips to indicate things by context. The open and closed nature
determined how the cask was rendered graphically. If open, the return
parameters, for example, would be shown like this:

// It's actual form: (|O||return|name|)

// How it's rendered on-screen:

+--------+
| return |
|+-------+
||
(|O|name|)

It has a popup which extends up out of the side. When it is closed,
it would be rendered like this:

(o||name|)

The double-|| on the left side indicates it has content there, and the
closed "o" would be used to access it. Similarly, the content on the
right-side would go down:

// It's actual form: (|name|a,b,c||O|)

// How it's rendered on-screen:

(|name|O|)
||
|+------+
| a,b,c |
+-------+

In addition, utility casks operate the same way. And I use the tag
".meta(name)" to give them a display name, as in:

~|lots of code goes here|~.name(fixup)

Then it's rendered on-screen as this when closed, allowing it to be
dragged around and dropped where needed:

~|o|fixup|~

Which allows it to be like this when opened:

+---------------+
| abc = NULL; |
| other_code(); |
| more_code(); |
|+--------------+
||
~|O|fixup|~

The GUI editor handles the re-display, while the hard-and-fast syntax
form exists in text form. But, since computers are our tools and
helpers, there's no reason why the two should not be explicitly tied
together in this supercomputer-on-a-graphics-card era.

> > -----
> > CAlive also introduces the "always_before" and "always_after" code blocks
> > for various things:
> >
> > // Note: the [once] syntax below indicates "once" is a keyword that
> > // is optional, same for [per_call].
> > while (some_condition)
> > {
> > // Code goes here
> >
> > } always_before [once] [per_call] {
> > // Code executes before the while loop begins
> > // If once is applied, then it only executes the first time
> > // the while loop is traversed throughout the lifetime of
> > // the program. If per_call is applied, then it will use
> > // a local flag to determine if it should be called.
> >
> > } always_after [once] [per_call] {
> > // Code executes after the while loop exits
> > // If once is applied, then it only executes the first time
> > // the while loop is traversed throughout the lifetime of
> > // the program. If per_call is applied, then it will use
> > // a local flag to determine if it should be called.
> > }
>
> Why not just write the code before the while loop, after it, or inside
> it as appropriate?

Encapsulation.
It's all about removing as much as is required from the author having
to figure things out all of hte time. That requirement will still be
there, but by visually putting the code related to the unless clauses
inside the loop, it's immediately obvious to even non-programmers
what it means.

BTW, I've used my wife and son as guinea pigs for some of this, so I
do have corroborating evidence to which I speak. :-)

> Again, it's going to take a /serious/ example to show any point here.
>
> And then you have to convince us that it is better than normal C or C++,
> possibly using exceptions or goto.
>
>
> > -----
> > CAlive also allows do loops to have their test clause at the top:
> >
> > do while {
> > // Code goes here
> >
> > // } unless (test) { blocks can go here
> >
> > }; // semicolon here is optional, and ignored
> >
> >
>
> In C, you have:
>
> while (x) {...};
>
> and
>
> do {...} while (x);
>
> Put the condition where it makes sense.

That's why I allow "do while" and "do { } while" ... they're both do
loops, and it makes more sense to keep them the same than to just use
"while" in one case, and "do" in another.

There are also some x-extensions I'll get into at a later point. I'm
sure you'll love those. :-)

Here's some previews in VXB++ syntax (XBASE-like) in case you can't wait:

http://www.visual-freepro.org/wiki/index.php/Flow_Control#FORX..ENDFORX
http://www.visual-freepro.org/wiki/index.php/Flow_Control#XIF..XELSEIF.2C_XFALLTHROUGH.2C_XGOTO.2C_XEXIT.2C_and_XRETRY
http://www.visual-freepro.org/wiki/index.php/Flow_Control#XELSE.2C_XOVERRIDE_and_XCANCEL

-----
I also introduce a line if statement:

lif (something) code1; code2; code3;
lelse code4; code5; code6;

It differs from the standard syntax:

if (something { code1; code2; code3; }
else { code4; code5; code6; }

...and for exactly the reasons you'd expect, lif and lelse are
fundamental things and they should be easier to read and understand.

-----
I also introduce a full-if statement which tests every condition
all the way through:

fif (x == 4 && y == 3)
{
// Both values were tested, and their results are in implicit
// structure of boolean variables called _fif.l1, _fif.l2, and
// so on.
}

The affixed names can also be changed with override definition casks
(shown here with extra spaces to break it out):

fif ( [|xtest|] x == 4 && [|ytest|] y == 3)
{
// The results are available through _fif.xtest, and _fif.ytest
// as well as _fif.l1 and _fif.l2, as they are created as a
// union.
}

And there's more. But in all honesty, I don't want to spend the day
defending myself. I'm 20+ years in considering these ideas, and I've
really spent the bulk of the last few years considering the finer
details and points as I've become a better C/C++ developer. They are
the things I want to see in a language, and I'm intent on adding them.

David Brown

unread,
Oct 30, 2015, 9:22:50 AM10/30/15
to
On 30/10/15 13:03, Ben Bacarisse wrote:
> David Brown <david...@hesbynett.no> writes:
> <snip>
>> I think Rick's "adhoc" functions are basically lambdas, or perhaps
>> simply nested functions (a gcc extension, and legal in many other
>> programming languages). There is always a bit of detail when talking
>> about such functions (how do you access local data in the surrounding
>> scope, how and when are variables captured, and so on) - but the
>> principle is there.
>
> Rick has stated that he does not want to learn about programming
> languages so he is bound to keep reinventing things, and coming up
> non-standard names for them.
>
>> I /think/ casks could also be handled by making and then calling a
>> lambda function at the same point:
>>
>> for (...)
>> {
>> if (some_function(~| abc = NULL; |~ &abc))
>> // Do something
>> }
>>
>> is the same as (if I've got the syntax correct):
>>
>> for (...)
>> {
>> if (some_function([&]{ abc = NULL;}(), &abc))
>
> You need ()s round the comma expression.

True.

> But since abc is in scope
> where the lambda is called, it serves no purpose. It can play a
> syntactic role in this situation -- by allowing declarations and a block
> of statements for example -- but that's all. But when that's what you
> are doing, gcc's ({...}) is clearer.

Agreed. But of course, simply putting "abc = NULL" in the sensible
place is even clearer.

>
>> // Do something
>> }
>
> But in this case it's also the same as a comma expression with an
> assignment. Rick needs to take more care pricking examples. A feature
> needs be illustrated with an example that needs it.
>

Yes, I'd like to see such an example too. While I know without doubt
that I would never use CAlive (for a good many reasons), it would be
nice to see a case where casks really give added value to the language.
Rick has invested a lot of time and effort in them, and received almost
completely negative feedback here - it would be nice to see that his
effort has not been entirely wasted.

Alternatively, if he keeps "pricking" examples like these and seeing
that others dislike them or can implement them easily in C, maybe he
will see that casks are not the marvel he hopes.


David Brown

unread,
Oct 30, 2015, 11:23:35 AM10/30/15
to
There is no sign of anyone being interested in CAlive, but several
people are still interested in figuring out what you mean by casks, and
why you would want them. New ideas can be interesting even though
CAlive itself is irrelevant.

>
> adhoc touched
> |params char* p
> {
> printf("Touched %s\n", p);
> }
>
> if ( x == 2 (|touched|"x"||) <||meta|iftrue|x||> <||mefa|iffalse|x||>
> || y == 1 (|touched|"y"||)
> || z == 3 (|touched|"z"||) <||meta|iftrue|z||> <||mefa|iffalse|z||>)
> {
> // Code goes here
>
> } else {
> // Code goes here
> }


bool doCode = false;
if (x == 2) {
touched("x");
iftrue("x");
doCode = true;
} else {
iffalse("x");
if (y == 1) {
touched("y");
doCode = true;
} else if (z == 3) {
touched("z");
iftrue("z");
doCode = true;
} else {
iffalse("z");
}
}
if (doCode) {
// Code goes here
} else {
// Code goes here
}


It could be arranged in several ways, depending on what you are actually
trying to do - something that is hard to see from such artificial
examples. Some people feel that using "goto" rather than a boolean
doCode is better, others might prefer to use multiple return statements.
There are many options without introducing a new syntax.

(And I thought || now meant "whitespace" ?)

>
> In each test, because the casks are inserted after the test, the
> execution of the (|touched|) cask indicates it made it that far
> through the || expression, and the result of each logic state
> will have triggered the appropriate iftrue() and iffalse() calls.
>
> And casks can be inserted anywhere employing similar abilities.
>
>>> switch (x)
>>> {
>>> case 2 <||meta|iftrue|> <||mefa|iffalse|>:
>>> // Code goes here
>>> break;
>>> }
>>
>> The "iftrue" part can go directly in the case, just before "Code goes
>> here". Again, the standard C is clearer and simpler than the casks.
>>
>> The "iffalse" part is harder - it is far from clear how it should
>> interact with other code. Should it be run for all cases other than 2?
>
> It would be fired in all cases top-down in the case statements until
> one which matches is found.
>
> CAlive also allows for non-const values in switch statements, as well
> as ranges of values (which I believe are also GCC extensions).

Case ranges are a good idea, but I'm a little sceptical about allowing
non-cost values. I think allowing constant values of other types (such
as strings) would be a more useful change. A key point about switches
is that the order does not matter (except for fall-through if you don't
have a "break") - it should not be a sequential series of tests for
efficiency reasons. That is hard to achieve with variable cases, and
impossible if cases depend on each other for ordering.

>
>> Should it be run before or after "iftrue" parts for other cases?
>> Should that depend on whether those cases are before or after case 2?
>>
>> Even if you have a single answer to that question, it is not going to be
>> obvious when used - and it will be a total mess if there are many such
>> clauses. It means that the actions taken in one case depend on the code
>> written in a different case - making the code confusing, and losing all
>> track of code flow. And as well as being extremely difficult for the
>> programmer to comprehend, it will hinder the compiler's abilities to
>> generate good object code.
>>
>> I would need to see a /very/ convincing real-life example before this
>> would make sense to me.
>
> There will be one at some point. CAlive is still a ways away from
> me bringing it into a tool you can download and test. I'm doing all
> of this development in my after-work hours, on weekends, and on
> holidays.

Don't worry about making it possible for others to download or test -
and as I have said before, I don't think it is a good use of your time.

But you certainly need to be able to write real, convincing examples
before it makes sense to try to implement them!
This is all crazy - I can't think of a better word for it. It's insane.

The sort of things you are putting into your casks are not little bits
of notes or comments. They are essential parts of the code and the
working of the program. You can't just pick parts of the language and
decide that /these/ bits will only be visible when you put your mouse
over them, or that /those/ bits will be hidden by default.

I'm sorry - I've been trying to be diplomatic, and trying to be
supportive and give constructive criticism and useful questions rather
than ridicule your ideas, but I have my limits.

>>> -----
>>> CAlive also introduces the "always_before" and "always_after" code blocks
>>> for various things:
>>>
>>> // Note: the [once] syntax below indicates "once" is a keyword that
>>> // is optional, same for [per_call].
>>> while (some_condition)
>>> {
>>> // Code goes here
>>>
>>> } always_before [once] [per_call] {
>>> // Code executes before the while loop begins
>>> // If once is applied, then it only executes the first time
>>> // the while loop is traversed throughout the lifetime of
>>> // the program. If per_call is applied, then it will use
>>> // a local flag to determine if it should be called.
>>>
>>> } always_after [once] [per_call] {
>>> // Code executes after the while loop exits
>>> // If once is applied, then it only executes the first time
>>> // the while loop is traversed throughout the lifetime of
>>> // the program. If per_call is applied, then it will use
>>> // a local flag to determine if it should be called.
>>> }
>>
>> Why not just write the code before the while loop, after it, or inside
>> it as appropriate?
>
> Encapsulation.

Name-dropping a technical term is not an explanation.
I do not take that as any sort of corroborating evidence.

>
>> Again, it's going to take a /serious/ example to show any point here.
>>
>> And then you have to convince us that it is better than normal C or C++,
>> possibly using exceptions or goto.
>>
>>
>>> -----
>>> CAlive also allows do loops to have their test clause at the top:
>>>
>>> do while {
>>> // Code goes here
>>>
>>> // } unless (test) { blocks can go here
>>>
>>> }; // semicolon here is optional, and ignored
>>>
>>>
>>
>> In C, you have:
>>
>> while (x) {...};
>>
>> and
>>
>> do {...} while (x);
>>
>> Put the condition where it makes sense.
>
> That's why I allow "do while" and "do { } while" ... they're both do
> loops, and it makes more sense to keep them the same than to just use
> "while" in one case, and "do" in another.

Call it "do while (x) { ... }" if you like, that's just syntactic
detail. The principle is the same.

>
> There are also some x-extensions I'll get into at a later point. I'm
> sure you'll love those. :-)
>
> Here's some previews in VXB++ syntax (XBASE-like) in case you can't wait:
>
> http://www.visual-freepro.org/wiki/index.php/Flow_Control#FORX..ENDFORX
> http://www.visual-freepro.org/wiki/index.php/Flow_Control#XIF..XELSEIF.2C_XFALLTHROUGH.2C_XGOTO.2C_XEXIT.2C_and_XRETRY
> http://www.visual-freepro.org/wiki/index.php/Flow_Control#XELSE.2C_XOVERRIDE_and_XCANCEL
>
> -----
> I also introduce a line if statement:
>
> lif (something) code1; code2; code3;
> lelse code4; code5; code6;
>
> It differs from the standard syntax:
>
> if (something { code1; code2; code3; }
> else { code4; code5; code6; }
>
> ...and for exactly the reasons you'd expect, lif and lelse are
> fundamental things and they should be easier to read and understand.
>

/How/ does "lif" and "lelse" differ from C's "if" and "else" ? If all
you are doing is making the group built-in, then I approve of the idea -
the optional brackets in C's "if" statements is a source of many errors.
But rather than inventing new keywords, just change those of C. Either
make brackets required, so that "if (x) " /must/ be followed by {, or
make the if statement end with an "endif" or "fi" statement:

if (x)
code1;
code2;
else
code3;
fi

There is no advantage in having two almost the same keywords for the
same thing.


> -----
> I also introduce a full-if statement which tests every condition
> all the way through:
>
> fif (x == 4 && y == 3)
> {
> // Both values were tested, and their results are in implicit
> // structure of boolean variables called _fif.l1, _fif.l2, and
> // so on.
> }
>

That's a terrible idea. It means that the interpretation of the
expression inside the brackets depends on its context. You should
strive to make your language as consistent as possible, not invent new
ways to make it inconsistent.

And don't invent implicit structures like that. Let people write "(x ==
4)" inside the code body and make your compiler figure out if it is most
efficient to re-do the check, or to store the results of the previous check.

> The affixed names can also be changed with override definition casks
> (shown here with extra spaces to break it out):
>
> fif ( [|xtest|] x == 4 && [|ytest|] y == 3)
> {
> // The results are available through _fif.xtest, and _fif.ytest
> // as well as _fif.l1 and _fif.l2, as they are created as a
> // union.
> }

bool xtest, ytest;
if ((xtest = (x == 4)) && (ytest = (y == 3))) ...

or

bool xtest = (x == 4);
bool ytest = (y == 3);
if (xtest && ytest) ....

It is going to be incredibly rare that anyone would need to make use of
such structures. Rather than inventing ever more complex structures,
keywords, and features that will almost never be used, let the user
write that extra line or two when needed.

>
> And there's more. But in all honesty, I don't want to spend the day
> defending myself. I'm 20+ years in considering these ideas, and I've
> really spent the bulk of the last few years considering the finer
> details and points as I've become a better C/C++ developer. They are
> the things I want to see in a language, and I'm intent on adding them.
>

It is entirely clear that you will go your own way, as usual. (It is
rare for anyone to change their minds as a result of a thread on
Usenet.) But I assume you are making these posts in the hope of getting
some feedback, so I give it as honestly and clearly as I can.


Malcolm McLean

unread,
Oct 30, 2015, 11:54:47 AM10/30/15
to
On Friday, October 30, 2015 at 1:22:50 PM UTC, David Brown wrote:
>
>
> Yes, I'd like to see such an example too. While I know without doubt
> that I would never use CAlive (for a good many reasons), it would be
> nice to see a case where casks really give added value to the language.
> Rick has invested a lot of time and effort in them, and received almost
> completely negative feedback here - it would be nice to see that his
> effort has not been entirely wasted.
>
As far as I see it a cask is a) a reinvention of a lambda function and b)
marked up so the IDE displays or hides the code according to mouse
position.

Ben Bacarisse

unread,
Oct 30, 2015, 12:12:50 PM10/30/15
to
Malcolm McLean <malcolm...@btinternet.com> writes:
<snip>
> As far as I see it a cask is a) a reinvention of a lambda function [...]

Lambda expressions have two main features: they can bind names, and they
have a value which is a function. I've seen no syntax that suggest
casks can bind names, and no example that shows casks evaluate to
function values.

<snip>
--
Ben.

Rick C. Hodgin

unread,
Oct 30, 2015, 12:26:14 PM10/30/15
to
Yup. A person could code that way if s/he wanted to.

> It could be arranged in several ways, depending on what you are actually
> trying to do - something that is hard to see from such artificial
> examples. Some people feel that using "goto" rather than a boolean
> doCode is better, others might prefer to use multiple return statements.
> There are many options without introducing a new syntax.
>
> (And I thought || now meant "whitespace" ?)

Only when it's the first non-whitespace character on a line, and not
part of another thing, such as an if, lif, fif, etc.

> > In each test, because the casks are inserted after the test, the
> > execution of the (|touched|) cask indicates it made it that far
> > through the || expression, and the result of each logic state
> > will have triggered the appropriate iftrue() and iffalse() calls.
> >
> > And casks can be inserted anywhere employing similar abilities.
> >
> >>> switch (x)
> >>> {
> >>> case 2 <||meta|iftrue|> <||mefa|iffalse|>:
> >>> // Code goes here
> >>> break;
> >>> }
> >>
> >> The "iftrue" part can go directly in the case, just before "Code goes
> >> here". Again, the standard C is clearer and simpler than the casks.
> >>
> >> The "iffalse" part is harder - it is far from clear how it should
> >> interact with other code. Should it be run for all cases other than 2?
> >
> > It would be fired in all cases top-down in the case statements until
> > one which matches is found.
> >
> > CAlive also allows for non-const values in switch statements, as well
> > as ranges of values (which I believe are also GCC extensions).
>
> Case ranges are a good idea, but I'm a little sceptical about allowing
> non-cost values. I think allowing constant values of other types (such
> as strings) would be a more useful change. A key point about switches
> is that the order does not matter (except for fall-through if you don't
> have a "break")

Of course the order matters. And in CAlive, it will matter directly
because you can inject casks at any point.

WYSIWYG in source code, through to output code, short of optimizations
which are visible in CAlive, as it shows every change made throughout
the optimization process.

But, the initial versions of CAlive will not support anything more
than the simplest optimizations.

> - it should not be a sequential series of tests for
> efficiency reasons. That is hard to achieve with variable cases, and
> impossible if cases depend on each other for ordering.

Non-constant values basically turn it into a more structured way of
creating if..else if..else if... statements. No need for { }
sequences, and the added ability to directly fall through.

> >> Should it be run before or after "iftrue" parts for other cases?
> >> Should that depend on whether those cases are before or after case 2?
> >>
> >> Even if you have a single answer to that question, it is not going to be
> >> obvious when used - and it will be a total mess if there are many such
> >> clauses. It means that the actions taken in one case depend on the code
> >> written in a different case - making the code confusing, and losing all
> >> track of code flow. And as well as being extremely difficult for the
> >> programmer to comprehend, it will hinder the compiler's abilities to
> >> generate good object code.
> >>
> >> I would need to see a /very/ convincing real-life example before this
> >> would make sense to me.
> >
> > There will be one at some point. CAlive is still a ways away from
> > me bringing it into a tool you can download and test. I'm doing all
> > of this development in my after-work hours, on weekends, and on
> > holidays.
>
> Don't worry about making it possible for others to download or test -
> and as I have said before, I don't think it is a good use of your time.

Well as you know it goes like this: When it's ready for me to use in
any kind of non-development state, it will then be ready for others to
use. So the two go hand-in-hand.

> But you certainly need to be able to write real, convincing examples
> before it makes sense to try to implement them!

Being as this is a new language, I have tried to demonstrate the
functionality of the operations. I think what I have shown makes
it clear. When I am able to actually introduce these abilities
into code, as through the compiler facilities of CAlive actually
being developed and working, such an example will be forthcoming.

I view the cask as a fundamental building block of all future
source code. I view the blocks of code that will be created more
like what I have in mind for my Logician software, which uses a
graphical node editor to allows things to be plugged up graphically,
and to be manipulate as objects in 3D space creating logical
structures rather than flat code bases. I want people to write
code more like they think... and that's where CAlive is ultimately
heading to.

CAlive will also be the fundamental compiler for use with Logician.
You have my permission to no longer reply to my posts if you want. I
know it would make my life a little nicer.

> The sort of things you are putting into your casks are not little bits
> of notes or comments. They are essential parts of the code and the
> working of the program. You can't just pick parts of the language and
> decide that /these/ bits will only be visible when you put your mouse
> over them, or that /those/ bits will be hidden by default.
>
> I'm sorry - I've been trying to be diplomatic, and trying to be
> supportive and give constructive criticism and useful questions rather
> than ridicule your ideas, but I have my limits.

Then please accept my invitation to bow out from all future discourse
regarding CAlive. I'm sure we'll both be better off for it.

> >>> -----
> >>> CAlive also introduces the "always_before" and "always_after" code blocks
> >>> for various things:
> >>>
> >>> // Note: the [once] syntax below indicates "once" is a keyword that
> >>> // is optional, same for [per_call].
> >>> while (some_condition)
> >>> {
> >>> // Code goes here
> >>>
> >>> } always_before [once] [per_call] {
> >>> // Code executes before the while loop begins
> >>> // If once is applied, then it only executes the first time
> >>> // the while loop is traversed throughout the lifetime of
> >>> // the program. If per_call is applied, then it will use
> >>> // a local flag to determine if it should be called.
> >>>
> >>> } always_after [once] [per_call] {
> >>> // Code executes after the while loop exits
> >>> // If once is applied, then it only executes the first time
> >>> // the while loop is traversed throughout the lifetime of
> >>> // the program. If per_call is applied, then it will use
> >>> // a local flag to determine if it should be called.
> >>> }
> >>
> >> Why not just write the code before the while loop, after it, or inside
> >> it as appropriate?
> >
> > Encapsulation.
>
> Name-dropping a technical term is not an explanation.

It is the reason why they exist. They are directly related to the
loops... so they are included within it.

Code outside of a loop can be related to the loop, or it can be related
to something else. By putting it inside the loop, that variable is
resolved, and turned into a constant... Simplify. Reduce.
Neither of them are programmers. And both of them are truly in all
ways not programmers. So, when I describe something to them, they
approach me with an honest desire to help me, and when I explain
something they give me criticism designed to help me. And they are
very good at it. Especially my wife.

> >> Again, it's going to take a /serious/ example to show any point here.
> >>
> >> And then you have to convince us that it is better than normal C or C++,
> >> possibly using exceptions or goto.
> >>
> >>
> >>> -----
> >>> CAlive also allows do loops to have their test clause at the top:
> >>>
> >>> do while {
> >>> // Code goes here
> >>>
> >>> // } unless (test) { blocks can go here
> >>>
> >>> }; // semicolon here is optional, and ignored
> >>>
> >>>
> >>
> >> In C, you have:
> >>
> >> while (x) {...};
> >>
> >> and
> >>
> >> do {...} while (x);
> >>
> >> Put the condition where it makes sense.
> >
> > That's why I allow "do while" and "do { } while" ... they're both do
> > loops, and it makes more sense to keep them the same than to just use
> > "while" in one case, and "do" in another.
>
> Call it "do while (x) { ... }" if you like, that's just syntactic
> detail. The principle is the same.

Yes. It's a syntax detail. But it also conveys the meaning that
these are both "do { } while" and "do while { }" loops, both do
loops.

That distinction means something.
I demonstrated the difference in my example above. It is a syntax
difference, and it conveys explicitly the meaning through use of
the lif and lelse keywords.

> > -----
> > I also introduce a full-if statement which tests every condition
> > all the way through:
> >
> > fif (x == 4 && y == 3)
> > {
> > // Both values were tested, and their results are in implicit
> > // structure of boolean variables called _fif.l1, _fif.l2, and
> > // so on.
> > }
> >
>
> That's a terrible idea. It means that the interpretation of the
> expression inside the brackets depends on its context. You should
> strive to make your language as consistent as possible, not invent new
> ways to make it inconsistent.
>
> And don't invent implicit structures like that. Let people write "(x ==
> 4)" inside the code body and make your compiler figure out if it is most
> efficient to re-do the check, or to store the results of the previous check.

I appreciate the advice. I'll take it under advisement.

> > The affixed names can also be changed with override definition casks
> > (shown here with extra spaces to break it out):
> >
> > fif ( [|xtest|] x == 4 && [|ytest|] y == 3)
> > {
> > // The results are available through _fif.xtest, and _fif.ytest
> > // as well as _fif.l1 and _fif.l2, as they are created as a
> > // union.
> > }
>
> bool xtest, ytest;
> if ((xtest = (x == 4)) && (ytest = (y == 3))) ...
>
> or
>
> bool xtest = (x == 4);
> bool ytest = (y == 3);
> if (xtest && ytest) ....
>
> It is going to be incredibly rare that anyone would need to make use of
> such structures. Rather than inventing ever more complex structures,
> keywords, and features that will almost never be used, let the user
> write that extra line or two when needed.

I'll take it under advisement.

> > And there's more. But in all honesty, I don't want to spend the day
> > defending myself. I'm 20+ years in considering these ideas, and I've
> > really spent the bulk of the last few years considering the finer
> > details and points as I've become a better C/C++ developer. They are
> > the things I want to see in a language, and I'm intent on adding them.
>
> It is entirely clear that you will go your own way, as usual.

It's what leaders do.

> (It is rare for anyone to change their minds as a result of a thread on
> Usenet.) But I assume you are making these posts in the hope of getting
> some feedback, so I give it as honestly and clearly as I can.

I have changed my mind on many things, the most recent of which was Bart's
contribution of the .. for auto-resolve. And there was one sometime
before that I can't remember... but it came also from comp.lang.c, and I
think it also came from Bart.

Rick C. Hodgin

unread,
Oct 30, 2015, 12:28:30 PM10/30/15
to
There is more than one type of cask. I doubt they all relate to
lambda functions.

The full intention of RDC and CAlive is to have an integrated compiler
that works together with the IDE to convey things that the developer
would desire to know about their code, and the compilation of their
code. It is also exclusively within the LiveCode environment, making
its integration with the debugger/editor almost a single unit. In
fact, it ultimately might be more so a single unit than I currently
envision.

Rick C. Hodgin

unread,
Oct 30, 2015, 12:32:55 PM10/30/15
to
On Friday, October 30, 2015 at 12:12:50 PM UTC-4, Ben Bacarisse wrote:
> Malcolm McLean <malcolm...@btinternet.com> writes:
> <snip>
> > As far as I see it a cask is a) a reinvention of a lambda function [...]
>
> Lambda expressions have two main features: they can bind names, and they
> have a value which is a function. I've seen no syntax that suggest
> casks can bind names,

I'm not sure what binding names means, but [|definition|] casks create
things at their location. In the fif () example above, it was like this:

fif (x == 2 && y == 3)
{
// The full-if statement evaluated every expression, and created
// an implicit local variable called _fif which contains members
// _l1, _l2, ... _lN as needed, indicating the result of each
// logical test
}

By using the definition cask, the names used for _lN can be overridden:

fif ( [|xtest|] x == 2 && [|ytest|] y == 3)

Now, in addition to _fif.l1 and _fifl2 there exists _fif.xtest, and
_fif.ytest.

> and no example that shows casks evaluate to
> function values.

All reference and utility casks evaluate to function values if the last
thing they do is call something which returns a value, AND they are the
only parameter in use at that point. In all other cases, the return
values of casks are discarded, unless they are used within nested casks,
in which case they will fall through and populate the associated
parameters (as CAlive supports multiple return values).

Kenny McCormack

unread,
Oct 30, 2015, 12:47:49 PM10/30/15
to
In article <n101t9$u5g$1...@dont-email.me>,
David Brown <david...@hesbynett.no> wrote:
...
>It is entirely clear that you will go your own way, as usual. (It is
>rare for anyone to change their minds as a result of a thread on
>Usenet.) But I assume you are making these posts in the hope of getting
>some feedback, so I give it as honestly and clearly as I can.

A few comments:

1) Re: Rick's proposed 'fif' statement (and similar constructs that
involve redefining the meaning of things like "&&" and "||"). I
think it is important to realize that Rick is an amateur language
designer (by his own statements - i.e., that is not a slam - it is
a fact based on his own statements) and his ideas reflect that.

The fact is that a lot of people don't really understand that &&
and || are (in C and most C-like languages) part of the expression
syntax and *not* part of the "if"/"while"/etc syntax. Since they
only see them used in the conditional/iterative statements, these
people assume that they are part of the syntax of those kinds of
statements. Therefore, it is entirely reasonable for them to
assume that their usage can be redefined in terms of the syntax of
those statements.

2) I don't like that many of you are trying to discourage Rick in his
pursuits. For one thing, as I've said elsewhere, this newsgroup
would be pretty boring without him - there's only so many times we
can go on debating how to prototype main() and/or whether or not
you should cast the return value of malloc(). As long as Rick is
willing to entertain us, I'm happy to be entertained.

For another, trying to do something that is impossible can often be
a good learning experience. This is true both at the personal
level and on an historical level. The best historical example of
this is alchemy - many useful and important things were discovered
along the way, even though the stated goal was in vain.

In fact, a similar tangle in going on in another forum that I
participate in. There, some guy is trying to do something that we
(the smart people on the forum) all know is impossible (say, like
"squaring the circle"). But many/most of the other smart people on
that forum are spending all their time telling him:
a) How impossible it is
and
b) That he should cease and desist immediately (and this in no
uncertain terms!)
I, on the other hand, have been telling him to continue (and to
ignore the others) on the theory that he will learn something from
the experience. And that, as they all say, is the important thing
(that's what it's all about!)

3) I actually think it is good to see how language design is done by an
amateur. Charming, like watching amateur sports. In fact, I
think a lot of us are blinded by the fact that we know too much
about implementation. People who understand implementation tend to
design languages that end up looking and behaving like, well, C.
Vis a vis, I think that many of the more esoteric scripting
languages were designed by people who don't understand
implementation. It is interesting to see how computer languages
get designed by artistic people rather than by comp-sci people.
Rick seems to be a good, living example of this.

--
I've been watching cat videos on YouTube. More content and closer to
the truth than anything on Fox.

Malcolm McLean

unread,
Oct 30, 2015, 12:57:50 PM10/30/15
to
On Friday, October 30, 2015 at 4:32:55 PM UTC, Rick C. Hodgin wrote:
> On Friday, October 30, 2015 at 12:12:50 PM UTC-4, Ben Bacarisse wrote:
> > Malcolm McLean <malcolm...@btinternet.com> writes:
> > <snip>
> > > As far as I see it a cask is a) a reinvention of a lambda function [...]
> >
> > Lambda expressions have two main features: they can bind names, and they
> > have a value which is a function. I've seen no syntax that suggest
> > casks can bind names,
>
> I'm not sure what binding names means, but [|definition|] casks create
> things at their location.
>
Lambda expressions take a snapshot of the names in scope. They can then be
called outside of that environment, even if the function where the lambda was
declared has gone out of scope.
So "cask" is a nice name for a lambda variant. Think of it as closing up the names,
and keeping them safe in a container, to use them when opened.

Rick C. Hodgin

unread,
Oct 30, 2015, 1:13:26 PM10/30/15
to
On Friday, October 30, 2015 at 12:47:49 PM UTC-4, Kenny McCormack wrote:
> The fact is that a lot of people don't really understand that &&
> and || are (in C and most C-like languages) part of the expression
> syntax and *not* part of the "if"/"while"/etc syntax. Since they
> only see them used in the conditional/iterative statements, these
> people assume that they are part of the syntax of those kinds of
> statements. Therefore, it is entirely reasonable for them to
> assume that their usage can be redefined in terms of the syntax of
> those statements.

See lines 4301, 4325, 4380, or if the line numbers are different, search
for "*tlLeft || *tlMiddle" or "llIsCAS = ":

https://github.com/RickCHodgin/libsf/blob/master/source/vjr/source/vjr_sup.cpp

|| was not re-defined. It is a new use of the character sequence when
it exists as the first non-whitespace character on a source code line,
and is not part of some other thing.

cout << "Understand?";

Rick C. Hodgin

unread,
Oct 30, 2015, 1:16:42 PM10/30/15
to
I have created a concept called "thisCode" for that ability. I do not
have it incorporated into CAlive because the references to things which
are not dynamically allocated are not conveyed in CAlive, but it exists
in VXB++ and VXB. In those languages, it uses the thisCode reference
sort of like a "this" reference which can be passed as a pointer to the environment from whichi it was derived, allowing access to all resources
from that relative location.

Rick C. Hodgin

unread,
Oct 30, 2015, 1:56:41 PM10/30/15
to
Okay, I understand now why you were thinking I had re-defined the ||
sequence across-the-board. I never conveyed anywhere that they must
appear as the first non-whitespace characters on a source code line.

-----
The easiest thing to do to remove all ambiguity is just add another
pipe sign to the two definitions. |||| for line comment, and ||| for
whitespace:

||||||||||
|||| Sample
|||
||| int x = 5;
||| printf("%d\n", x);
|||
||||||

That would probably work. I'll consider it.

Ben Bacarisse

unread,
Oct 30, 2015, 2:33:50 PM10/30/15
to
Malcolm McLean <malcolm...@btinternet.com> writes:

> On Friday, October 30, 2015 at 4:32:55 PM UTC, Rick C. Hodgin wrote:
>> On Friday, October 30, 2015 at 12:12:50 PM UTC-4, Ben Bacarisse wrote:
>> > Malcolm McLean <malcolm...@btinternet.com> writes:
>> > <snip>
>> > > As far as I see it a cask is a) a reinvention of a lambda function [...]
>> >
>> > Lambda expressions have two main features: they can bind names, and they
>> > have a value which is a function. I've seen no syntax that suggest
>> > casks can bind names,
>>
>> I'm not sure what binding names means, but [|definition|] casks create
>> things at their location.
>>
> Lambda expressions take a snapshot of the names in scope. They can
> then be called outside of that environment, even if the function where
> the lambda was declared has gone out of scope. So "cask" is a nice
> name for a lambda variant.

They still appear to lack all the key attributes of a lambda (for
example Rick stated that they don't evaluate to function values).
Unless almost everything that is code fits your meaning of "lambda
variant" they don't seem to fit either.

<snip>
--
Ben.

David Brown

unread,
Oct 30, 2015, 5:28:16 PM10/30/15
to
On 30/10/15 19:33, Ben Bacarisse wrote:
> Malcolm McLean <malcolm...@btinternet.com> writes:
>
>> On Friday, October 30, 2015 at 4:32:55 PM UTC, Rick C. Hodgin wrote:
>>> On Friday, October 30, 2015 at 12:12:50 PM UTC-4, Ben Bacarisse wrote:
>>>> Malcolm McLean <malcolm...@btinternet.com> writes:
>>>> <snip>
>>>>> As far as I see it a cask is a) a reinvention of a lambda function [...]
>>>>
>>>> Lambda expressions have two main features: they can bind names, and they
>>>> have a value which is a function. I've seen no syntax that suggest
>>>> casks can bind names,
>>>
>>> I'm not sure what binding names means, but [|definition|] casks create
>>> things at their location.
>>>
>> Lambda expressions take a snapshot of the names in scope. They can
>> then be called outside of that environment, even if the function where
>> the lambda was declared has gone out of scope. So "cask" is a nice
>> name for a lambda variant.
>
> They still appear to lack all the key attributes of a lambda (for
> example Rick stated that they don't evaluate to function values).
> Unless almost everything that is code fits your meaning of "lambda
> variant" they don't seem to fit either.
>

I think the point of the cask/lambda comparison is that many of the
things that can be done with casks could be done with lambdas - not that
casks can do all that lambdas can do. (The "adhoc" functions are closer
to being able to duplicate lambdas.)


Ben Bacarisse

unread,
Oct 30, 2015, 7:03:30 PM10/30/15
to
That may well be true, but I was not commenting on a remark that lambdas
can do much or all of what casks can do, I was commenting on two remarks
said something else entirely: "a cask is [...] a reinvention of a
lambda" and "'cask' is a nice name for a lambda variant". The first
appears to be flat-out wrong, and the second is only correct if "lambda
variant" is used to mean "small subset of a lambda's attributes".

<snip>
--
Ben.

Malcolm McLean

unread,
Oct 31, 2015, 4:35:50 AM10/31/15
to
On Friday, October 30, 2015 at 11:03:30 PM UTC, Ben Bacarisse wrote:
> David Brown <david...@hesbynett.no> writes:
>
> That may well be true, but I was not commenting on a remark that lambdas
> can do much or all of what casks can do, I was commenting on two remarks
> said something else entirely: "a cask is [...] a reinvention of a
> lambda" and "'cask' is a nice name for a lambda variant". The first
> appears to be flat-out wrong, and the second is only correct if "lambda
> variant" is used to mean "small subset of a lambda's attributes".
>
The purpose of a cask is to perform enclosure, surely? It's a
better name than "lambda", which as far as I can tell is just
an arbitrary Greek letter.

Ben Bacarisse

unread,
Oct 31, 2015, 7:39:34 AM10/31/15
to
Malcolm McLean <malcolm...@btinternet.com> writes:

> On Friday, October 30, 2015 at 11:03:30 PM UTC, Ben Bacarisse wrote:
>> David Brown <david...@hesbynett.no> writes:
>>
>> That may well be true, but I was not commenting on a remark that lambdas
>> can do much or all of what casks can do, I was commenting on two remarks
>> said something else entirely: "a cask is [...] a reinvention of a
>> lambda" and "'cask' is a nice name for a lambda variant". The first
>> appears to be flat-out wrong, and the second is only correct if "lambda
>> variant" is used to mean "small subset of a lambda's attributes".
>>
> The purpose of a cask is to perform enclosure, surely?

A {...} block also encloses code. Why do you think a "cask" is like a
function-valued expression rather being than a block of code? I don't
see anything in the examples to suggest that "casks" are like anonymous
functions.

> It's a
> better name than "lambda", which as far as I can tell is just
> an arbitrary Greek letter.

X can't be a better name for Y if X really means Z. If a "cask" really
turns out to be a function expression, I'll agree -- the name is better
than lambda -- but there is currently no evidence that a "cask" is a
function expression. I think it's a name for something that neither of
us understands (but if you do know what they are, please explain them --
Rick can't).

--
Ben.

David Brown

unread,
Oct 31, 2015, 12:04:21 PM10/31/15
to
On 30/10/15 17:47, Kenny McCormack wrote:
> In article <n101t9$u5g$1...@dont-email.me>,
> David Brown <david...@hesbynett.no> wrote:
> ...
>> It is entirely clear that you will go your own way, as usual. (It is
>> rare for anyone to change their minds as a result of a thread on
>> Usenet.) But I assume you are making these posts in the hope of getting
>> some feedback, so I give it as honestly and clearly as I can.
>
> A few comments:
>
> 1) Re: Rick's proposed 'fif' statement (and similar constructs that
> involve redefining the meaning of things like "&&" and "||"). I
> think it is important to realize that Rick is an amateur language
> designer (by his own statements - i.e., that is not a slam - it is
> a fact based on his own statements) and his ideas reflect that.
>
> The fact is that a lot of people don't really understand that &&
> and || are (in C and most C-like languages) part of the expression
> syntax and *not* part of the "if"/"while"/etc syntax. Since they
> only see them used in the conditional/iterative statements, these
> people assume that they are part of the syntax of those kinds of
> statements. Therefore, it is entirely reasonable for them to
> assume that their usage can be redefined in terms of the syntax of
> those statements.

Are you saying that Rick's idea for how "fif" should change && and || is
because he doesn't understand how they really work, or are you saying
his idea is a good one because a lot of other people don't understand
how they work?

It would make sense to me if he decided to make each half of && and ||
fully evaluated at all times - not just in "fif" statements. It would
also be possible to ban expressions with side-effects in "if" statements
- then there is no logical difference between full evaluation or
short-circuit evaluation.

>
> 2) I don't like that many of you are trying to discourage Rick in his
> pursuits. For one thing, as I've said elsewhere, this newsgroup
> would be pretty boring without him - there's only so many times we
> can go on debating how to prototype main() and/or whether or not
> you should cast the return value of malloc(). As long as Rick is
> willing to entertain us, I'm happy to be entertained.

I am not trying to discourage Rick - merely help him focus instead of
trying to do /everything/ at once. I am quite happy to see his posts on
CAlive here - most of his ideas for the language are not good IMHO, but
occasionally he has something that can inspire new techniques in C
programming. And as you say, the threads can be more entertaining than
the somewhat dry discussions that sometimes occur in other threads.

>
> For another, trying to do something that is impossible can often be
> a good learning experience. This is true both at the personal
> level and on an historical level. The best historical example of
> this is alchemy - many useful and important things were discovered
> along the way, even though the stated goal was in vain.

There is something in that, but who knows how many other useful things
would have been discovered if the same intelligence and dedication had
been targeted at more fruitful goals? Isaac Newton made enormous
contributions to science and mathematics in his early years, but most of
his adult life after that was wasted on alchemy (and some rather
heretical theology and downright evil political manipulations). If he
had stuck to maths and physics, he could have done so much more.

But I am happy to encourage learning for learning's sake, and a
/limited/ pursuit of the impossible can be useful.

>
> In fact, a similar tangle in going on in another forum that I
> participate in. There, some guy is trying to do something that we
> (the smart people on the forum) all know is impossible (say, like
> "squaring the circle"). But many/most of the other smart people on
> that forum are spending all their time telling him:
> a) How impossible it is
> and
> b) That he should cease and desist immediately (and this in no
> uncertain terms!)
> I, on the other hand, have been telling him to continue (and to
> ignore the others) on the theory that he will learn something from
> the experience. And that, as they all say, is the important thing
> (that's what it's all about!)

It is also through trying to do the impossible that you can really
understand /why/ it is impossible. And of course, very rarely someone
actually manages to do what everyone else says was impossible. Still,
it is useful to have a realistic idea of the scope of the problem.

>
> 3) I actually think it is good to see how language design is done by an
> amateur. Charming, like watching amateur sports. In fact, I
> think a lot of us are blinded by the fact that we know too much
> about implementation. People who understand implementation tend to
> design languages that end up looking and behaving like, well, C.
> Vis a vis, I think that many of the more esoteric scripting
> languages were designed by people who don't understand
> implementation. It is interesting to see how computer languages
> get designed by artistic people rather than by comp-sci people.
> Rick seems to be a good, living example of this.
>

"Charming" it may be, but again I think a touch of realism is in order.
Remember, Rick does not see himself as an amateur here (though he is
quite open about his lack of academic training in the subject) - he
believes he has special god-given skills that exceed those of mere
mundane humans, and that his language is divinely destined to take over
the computing world (at least for those programmers who are not
possessed by daemons).


Rick C. Hodgin

unread,
Oct 31, 2015, 12:48:29 PM10/31/15
to
On Saturday, October 31, 2015 at 12:04:21 PM UTC-4, David Brown wrote:
> Remember, Rick does not see himself as an amateur here

I acknowledge fully that I am an amateur.

Kenny McCormack

unread,
Oct 31, 2015, 1:51:17 PM10/31/15
to
In article <n12olh$o5v$1...@dont-email.me>,
David Brown <david...@hesbynett.no> wrote:
...
>> The fact is that a lot of people don't really understand that &&
>> and || are (in C and most C-like languages) part of the expression
>> syntax and *not* part of the "if"/"while"/etc syntax. Since they
>> only see them used in the conditional/iterative statements, these
>> people assume that they are part of the syntax of those kinds of
>> statements. Therefore, it is entirely reasonable for them to
>> assume that their usage can be redefined in terms of the syntax of
>> those statements.
>
>Are you saying that Rick's idea for how "fif" should change && and || is
>because he doesn't understand how they really work, or are you saying
>his idea is a good one because a lot of other people don't understand
>how they work?

First of all, nothing I say should be taken as defending or endorsing
anything Rick proposes. I think his ideas are universally nutty - fun and
entertaining, but utterly nutty.

I think that in Rick's mind, && and || are part of the syntax of the
conditional/iterative commands (I.e., if, while, for - and maybe others,
not sure if I have covered them all) rather than part of the syntax of C
arithmetic expressions.

Imagine if you will a C-like language in which && and || are *not* part of
the expression syntax. Imagine further that in this hypothetical C-like
language, && and || *are* part of the syntax of if/while/for. This seems
to be the world that Rick inhabits.

>It would make sense to me if he decided to make each half of && and ||
>fully evaluated at all times - not just in "fif" statements.

In this alternative world, && and || would not be part of the expression
syntax at all - so they would never be evaluated at all, *except* in 'fif'
statements.

...
>"Charming" it may be, but again I think a touch of realism is in order.
> Remember, Rick does not see himself as an amateur here (though he is
>quite open about his lack of academic training in the subject) - he
>believes he has special god-given skills that exceed those of mere
>mundane humans, and that his language is divinely destined to take over
>the computing world (at least for those programmers who are not
>possessed by daemons).

No. As Rick's followup confirms, he *is* an amateur language designer.

Note, BTW, that "amateur" does not mean "unskilled", although that is how
the term is often used, both in the "real world" and in this newsgroup in
particular.

--
"I think I understand delicate, but why do I have to wash my hands, and
be standing in cold water when doing it?"

Kaz Kylheku <k...@kylheku.com> in comp.lang.c

Malcolm McLean

unread,
Oct 31, 2015, 3:04:44 PM10/31/15
to
It's not clear to me whether "casks" are meant to capture code for
execution later, or if they merely package it up for display in a GUI
when the mouse hovers over the cask symbol.

They might well have different scoping rules to lambdas - since they
have been derived independently, you'd expect some differences.

But neither lambda calculus nor the cask was my personal invention,
I'm not especially well qualified to comment, particularly when the
inventer of the cask is here.

David Brown

unread,
Oct 31, 2015, 7:10:34 PM10/31/15
to
On 31/10/15 18:51, Kenny McCormack wrote:
> In article <n12olh$o5v$1...@dont-email.me>,
> David Brown <david...@hesbynett.no> wrote:
> ...
>>> The fact is that a lot of people don't really understand that &&
>>> and || are (in C and most C-like languages) part of the expression
>>> syntax and *not* part of the "if"/"while"/etc syntax. Since they
>>> only see them used in the conditional/iterative statements, these
>>> people assume that they are part of the syntax of those kinds of
>>> statements. Therefore, it is entirely reasonable for them to
>>> assume that their usage can be redefined in terms of the syntax of
>>> those statements.
>>
>> Are you saying that Rick's idea for how "fif" should change && and || is
>> because he doesn't understand how they really work, or are you saying
>> his idea is a good one because a lot of other people don't understand
>> how they work?
>
> First of all, nothing I say should be taken as defending or endorsing
> anything Rick proposes. I think his ideas are universally nutty - fun and
> entertaining, but utterly nutty.
>

OK.

> I think that in Rick's mind, && and || are part of the syntax of the
> conditional/iterative commands (I.e., if, while, for - and maybe others,
> not sure if I have covered them all) rather than part of the syntax of C
> arithmetic expressions.
>
> Imagine if you will a C-like language in which && and || are *not* part of
> the expression syntax. Imagine further that in this hypothetical C-like
> language, && and || *are* part of the syntax of if/while/for. This seems
> to be the world that Rick inhabits.

Only Rick can tell us if that's the case, or merely the impression you
have got from his posts. (An alternative way to make Rick's varying
definitions of && and || consistent would be to say that in CAlive,
these /are/ part of the syntax of if/while/for, and are not usable in
general expressions. I don't think that would be a good idea, but it
might be less bad.)

>
>> It would make sense to me if he decided to make each half of && and ||
>> fully evaluated at all times - not just in "fif" statements.
>
> In this alternative world, && and || would not be part of the expression
> syntax at all - so they would never be evaluated at all, *except* in 'fif'
> statements.
>
> ...
>> "Charming" it may be, but again I think a touch of realism is in order.
>> Remember, Rick does not see himself as an amateur here (though he is
>> quite open about his lack of academic training in the subject) - he
>> believes he has special god-given skills that exceed those of mere
>> mundane humans, and that his language is divinely destined to take over
>> the computing world (at least for those programmers who are not
>> possessed by daemons).
>
> No. As Rick's followup confirms, he *is* an amateur language designer.
>
> Note, BTW, that "amateur" does not mean "unskilled", although that is how
> the term is often used, both in the "real world" and in this newsgroup in
> particular.
>

Point taken. He is very definitely not doing this for the money, and
therefore an amateur. But he does believe himself to be highly skilled
in the field of language design, although he has freely stated that he
is untrained and uneducated (in this field - I don't know his education
in other fields).


Rick C. Hodgin

unread,
Oct 31, 2015, 8:12:10 PM10/31/15
to
I've already answered this question. Nobody listened.

My use of the || sequence was a new use of the sequence, and not a
removal of its previous use. I even included an example seen in
C++ which was similar:

cout << "Understand?";

Where "<<" was re-used from its other meaning in these contexts.

The || was a whitespace only if it appeared at the start of a line as
the first non-whitespace character. If it appeared anywhere after that,
or as part of an expression, then it was not a whitespace, but was then
the OR logic condition.

> >> It would make sense to me if he decided to make each half of && and ||
> >> fully evaluated at all times - not just in "fif" statements.
> >
> > In this alternative world, && and || would not be part of the expression
> > syntax at all - so they would never be evaluated at all, *except* in 'fif'
> > statements.
> >
> > ...
> >> "Charming" it may be, but again I think a touch of realism is in order.
> >> Remember, Rick does not see himself as an amateur here (though he is
> >> quite open about his lack of academic training in the subject) - he
> >> believes he has special god-given skills that exceed those of mere
> >> mundane humans, and that his language is divinely destined to take over
> >> the computing world (at least for those programmers who are not
> >> possessed by daemons).
> >
> > No. As Rick's followup confirms, he *is* an amateur language designer.
> >
> > Note, BTW, that "amateur" does not mean "unskilled", although that is how
> > the term is often used, both in the "real world" and in this newsgroup in
> > particular.
>
> Point taken. He is very definitely not doing this for the money, and
> therefore an amateur. But he does believe himself to be highly skilled
> in the field of language design, although he has freely stated that he
> is untrained and uneducated (in this field - I don't know his education
> in other fields).

I do not think I have great skill in language design.

I do think I look at fundamentals well, and then the things I build go
up from there. I consider that to be a side-effect of me having spent
so many years coding almost exclusively in assembly for all personal
projects. Because of that experience, I began to innately view data
from the machine level. It has notably impacted all aspects of the
way I view data processing and programming languages.

Rick C. Hodgin

unread,
Oct 31, 2015, 8:56:21 PM10/31/15
to
Casks are fully expanded forms in source code. They can have return
values, function names, and parameters when in the form of a
(|reference|) cask, or a ~|utility|~ cask:

(||return|function_name|param1, param2, param3, ...||)
~||return|function_name|param1, param2, param3, ...||~

(|reference|) casks are used to call other things (functions, adhocs,
member functions), whereas ~|utility|~ casks can do that, but they
are designed more for injecting whatever code where you want it to
be:

~|x = 5; printf("%d\n", my_function(x));|~

And then to simplify them in the GUI editor, there are additional
parts which can be added:

(||return|function_name|param1, param2, param3, ...||).name(update_total)
~|x = 5; printf("%d\n", my_function(x));|~.name(debug_print)

So that in the GUI editor they will appear in their short forms:

(o|update_total|o)
~|debug_print|~

Since casks are enclosed expressions, they can be inserted anywhere in
code. If they are inserted before a parameter is used, they will be
called before that parameter is put on the stack. If they're inserted
after, then they'll be called after it's on the stack. If they're
inserted before a logic test, then they'll be called before the test
is made. If they're inserted after a logic test, then they'll be called
after the logic test is made (if the logic then reached that far, for
example).

And so on...

-----
There are two more types of casks:

[|definition|]
<|logic|>

[|definition|] casks alter the way things are defined. You can put
in overrides, or augments to their definition. An example people
might be aware of would be:

char p [|const|];
// same as "const char p;"

Why would someone do this? Casks show up graphically in the editor,
and it may be more eye catching to see something which looks like this
in the GUI editor:

[char p];

Where the coloring of the "char p" portion is highlighted so that it
conveys the const nature without the keyword const. That's just an
example, by the way, but one I will probably include, along with other
similar ones.

-----
<|logic|> casks respond to true or false conditions set by flow control
operators, or they can inject their own as the left-most place in the
cask, then acting like a ((cond) ? iftrue : iffalse) expression:

<||cond|iftrue|iffalse||>

There are specific types, however, which are called META and MEFA, for
true and false, respectively:

<|meta|iftrue||>
<|mefa|iffalse||>

In these cases, these casks can be added to expressions and then will
signal the code based on the logic condition result:

if (x == 5 <|meta|iftrue||> <|meta|iffalse||>)
{
// Normal code here
}

In this example, the equivalent code would be:

llTest = (x == 5);
if (!llTest)
{
iffalse();

} else {
iftrue();
// Normal code here
}

And they can be inserted anywhere there are logic tests.

There are two other types of logic cask which follows the meta/mefa form
that I haven't introduced yet. They relate to new features of CAlive:

<|meia|> // Inquiry signal handler casks
<|mema|> // Message handler casks

If you think a line might throw an exception, which is called an inquiry
in CAlive, then you can attach a <|meia|> logic cask to it, and when
the inquiry happens, it will trigger that code:

some_function() <|meia|inquiry_handler||>;

Now, if something in some_function() or lower triggers an inquiry, it
will come back to this point and call the inquiry_handler() function.

And if there are specific types, then it can be moved to the left-most
slot for the testing:

some_function() <||_OUT_OF_MEMORY|meia|inquiry_handler_memory||>
<||_FLOATING_POINT|meia|inquiry_handler_fp||>
<|meia|inquiry_handler_default||>;

In this case, those two types of inquirys are handled explicitly, with
all others falling through to the default handler. If the default
handler wasn't specified, then other inquirys would not be handld here.

And <|meia|> casks can be inserted anywhere. I also introduce a special
flow control block which is similar to try..catch which handles inquiries.

-----
<|mema|> are message hander casks. It is a new CAlive feature to allow
not only a return value to be returned, but also a message. Messages
are available specifically to trigger <|mema|> casks, and are ignored
otherwise. Messages can return any combination of an integer, pointer
to text, or a pointer to any other thing, as int num, char* msg, and
void* p members.

void handler_message(char* p, int i)
{
printf("%s on %d\n", p, i);
}

some_function() <|mema|handler_message(mema.msg, mema.num)||>;

void some_function(void)
{
if (date_is_monday_thru_friday)
return message "Hi, mom!", day_of_week_number;
}

In this case, the message would be returned if the logic test passed,
and it would trigger the handler_message() function only in that case.
By embedding a ~|utility|~ cask within the <|mema|> cask, it then also
becomes possible to handle direct branching based on the returned
message, though this is typically handled through the flow { } blocks,
which I have not yet introduced, though I did introduce them many
months ago.

> They might well have different scoping rules to lambdas - since they
> have been derived independently, you'd expect some differences.
>
> But neither lambda calculus nor the cask was my personal invention,
> I'm not especially well qualified to comment, particularly when the
> inventer of the cask is here.

I doubt this was a help. It's a lot of explanation about things which
to other people aren't real yet. You don't have a tool to sit down
and play with it and re-interpret my wordy explanations into the way
you think... so until then, it will just have to be a curiosity most
likely.

Malcolm McLean

unread,
Nov 1, 2015, 6:06:24 AM11/1/15
to
On Sunday, November 1, 2015 at 12:56:21 AM UTC, Rick C. Hodgin wrote:
>
> > It's not clear to me whether "casks" are meant to capture code for
> > execution later, or if they merely package it up for display in a GUI
> > when the mouse hovers over the cask symbol.
>
> Casks are fully expanded forms in source code. They can have return
> values, function names, and parameters when in the form of a
> (|reference|) cask, or a ~|utility|~ cask:
>
> (||return|function_name|param1, param2, param3, ...||)
> ~||return|function_name|param1, param2, param3, ...||~
>
> (|reference|) casks are used to call other things (functions, adhocs,
> member functions), whereas ~|utility|~ casks can do that, but they
> are designed more for injecting whatever code where you want it to
> be:
>
> ~|x = 5; printf("%d\n", my_function(x));|~
>
> > But neither lambda calculus nor the cask was my personal invention,
> > I'm not especially well qualified to comment, particularly when the
> > inventer of the cask is here.
>
> I doubt this was a help. It's a lot of explanation about things which
> to other people aren't real yet. You don't have a tool to sit down
> and play with it and re-interpret my wordy explanations into the way
> you think... so until then, it will just have to be a curiosity most
> likely.
>
I think you need to read up on lambda functions and get au fait with them.
They're very much flavour of the month, and a lot of theoretical work
has been done on them. You don't have to understand it fully to have a
reasonable understanding of the terminology.

I think you'll realise that casks are similar to lambdas, and can probably be
recast or reformulated to make them essentially equivalent. The inventive step
is then a) the cask expands in a GUI to show the source, otherwise hides it,
b) we've got a classification and maybe expansion of the idea, so we've got a
distinction between casks which call subroutines and casks which don't,
casks which can throw exceptions (not allowed in lambda calculus, and in fact
driving coach and horses through the theory, but possibly something to allow
for real programming languages), and casks which can't, casks which are
booleans and designed for flow control and casks which are general-purpose.

Then I think you'd have something really worthwhile to offer, and you'd be
talking the same language as lambdas. Also, I think you'd realise that the
scoping rules, maybe can be changed to make casks more powerful.

David Brown

unread,
Nov 1, 2015, 9:24:34 AM11/1/15
to
You post a great deal - it's hard to catch everything, and easy to
forget some details, so sometimes you'll have to repeat things.

>
> My use of the || sequence was a new use of the sequence, and not a
> removal of its previous use. I even included an example seen in
> C++ which was similar:
>
> cout << "Understand?";
>
> Where "<<" was re-used from its other meaning in these contexts.

The symbol has a different meaning here, but the same syntax. However,
if you overload && or || in C++, you lose the short-circuit behaviour -
this is why overloading these operators is strongly discouraged.

But a key difference is that in C++, the behaviour (overloading) of the
operators is dependent on the types of surrounding expressions, while
you are proposing that it depends on whether or not they are part of an
"if" or a "fif". That leads quickly to confusion and inconsistency.

For example:

bool printif(bool b) {
if (b) printf("It's true!\n");
return b;
}

extern bool test1(void);
extern bool test2(void);

void foo1(void) {
if (test1() && test2()) ... // Short-circuit
fif (test1() && test2()) ... // Always calls test1 and test2
printf(test1() && test2()) // Short-circuit

bool t1 = test1();
bool t2 = test2();
if (t1 && t2) ... // Effectively a "fif"

fif (printf(test1() && test2())) ... // ?
}

On this last line, the && is used in the context of a simple expression,
and should therefore be short-circuit. It is also used inside a fif,
and should therefore be fully evaluated.

I am sure that you could define good enough rules to make this
ambiguous. But what you end up with is something confusing to the
programmer - he has to look up the rules to figure out what is actually
happening, and that is no help to anyone.

Given that it is extraordinarily rare that a "fif" statement would be
useful, and it is extremely clear and easy to get the desired effect
with a normal "if", I think the whole "fif" idea is a bad one.


>
> The || was a whitespace only if it appeared at the start of a line as
> the first non-whitespace character. If it appeared anywhere after that,
> or as part of an expression, then it was not a whitespace, but was then
> the OR logic condition.

What about this:

if ((x == 1)
|| (x == 2)
|| (x == 3)
)} ....

That might be a poor way to lay out code, but in picking syntax and
features you have to think about how /others/ can get things wrong, not
just how /you/ would get it right. And again, you can define
unambiguous language rules to remedy such cases - but it is definitely
not clear and convenient for the user here.
I certainly agree that a good grounding in assembly is useful for
language design, especially for a low-level compiled language. It is
not enough (especially when limited to x86, as I think is the case for
your assembly experience), but it is definitely a good thing.


Rick C. Hodgin

unread,
Nov 1, 2015, 9:37:32 AM11/1/15
to
I am not proposing that.

> that it depends on whether or not they are part of an
> "if" or a "fif". That leads quickly to confusion and inconsistency.

You do not understand. And I don't know why you don't understand. I
also don't think you realize that "fif" is a new thing which exists,
but it is not to replace "if". It exists separately as an option. I
also add "lif" which is a "line if" which doesn't require { } blocks
to encompass code which is on the same line.

Now, for the third time, I am not proposing that || be treated
differently when it's part of an "if" ... but only when it's not the
first non-whitepsace character on a line, or is part of any expression
(meaning it has to be inside parenthesis, for example).

I have also never mentioned anything about && so I don't know where
you've pulled that from.

> For example:
>
> bool printif(bool b) {
> if (b) printf("It's true!\n");
> return b;
> }
>
> extern bool test1(void);
> extern bool test2(void);
>
> void foo1(void) {
> if (test1() && test2()) ... // Short-circuit
> fif (test1() && test2()) ... // Always calls test1 and test2
> printf(test1() && test2()) // Short-circuit
>
> bool t1 = test1();
> bool t2 = test2();
> if (t1 && t2) ... // Effectively a "fif"
>
> fif (printf(test1() && test2())) ... // ?
> }
>
> On this last line, the && is used in the context of a simple expression,
> and should therefore be short-circuit. It is also used inside a fif,
> and should therefore be fully evaluated.
>
> I am sure that you could define good enough rules to make this
> ambiguous. But what you end up with is something confusing to the
> programmer - he has to look up the rules to figure out what is actually
> happening, and that is no help to anyone.
>
> Given that it is extraordinarily rare that a "fif" statement would be
> useful, and it is extremely clear and easy to get the desired effect
> with a normal "if", I think the whole "fif" idea is a bad one.

I recognize you think this. I appreciate your input.

The concept stands. CAlive WILL include fifs.

> > The || was a whitespace only if it appeared at the start of a line as
> > the first non-whitespace character. If it appeared anywhere after that,
> > or as part of an expression, then it was not a whitespace, but was then
> > the OR logic condition.
>
> What about this:
>
> if ((x == 1)
> || (x == 2)
> || (x == 3)
> )} ....

The || is part of an expression. It exists between parenthesis. It is
evaluated as such.

> That might be a poor way to lay out code, but in picking syntax and
> features you have to think about how /others/ can get things wrong, not
> just how /you/ would get it right. And again, you can define
> unambiguous language rules to remedy such cases - but it is definitely
> not clear and convenient for the user here.

I code like that. I place my operators at the start of each line because
of my reading issues. I align them vertically so I can see what's going
on. If I have mixed logic operators they fall wherever they need to, but
I spend some time making sure things are aligned on purpose, and for that
reason.
Assembly language in general teaches fundamental access to data,
regardless of the ISA. I've also spent a fair amount of time studying
IA-64 and ARM, as well as piecemeal bits about other architectures as
they came up on Usenet discussions, and various searches and reads.

-----
This whole discussion is moot now anyway, as I've simply re-defined
the whitespace to be |||, and the comment to be ||||, making them three
characters, and four or more characters, respectively. So, perhaps now
you can move on.

Philip Lantz

unread,
Nov 1, 2015, 2:45:53 PM11/1/15
to
Kenny McCormack wrote:
>
> In article <MPG.309c972...@news.eternal-september.org>,
> Philip Lantz <p...@canterey.us> wrote:
> >Rick C. Hodgin wrote:
> >>
> >> On Thursday, October 29, 2015 at 9:25:39 PM UTC-4, Ian Collins wrote:
> >> > Rick C. Hodgin wrote:
> >> > > On Thursday, October 29, 2015 at 5:48:26 PM UTC-4, Bart wrote:
> >> > >> Does ~|....|~ denote a bit of code that is not immediately evaluated
> >> > >> (maybe like QUOTE in Lisp)?
> >> > >
> >> > > The ~|utility|~ cask is an arbitrary injection of any code. It will
> >> > > be inserted at whatever point you insert the cask in a statement.
> >> > > The contents of the utility can contain anything. If it is a larger
> >> > > block it will be filled with multi-line content between the ~| and |~
> >> > > sides. However, CAlive provides for another feature whenever larger
> >> > > bits of code are required. They would typically be used, along with
> >> > > the (|reference|) casks, instead of the ~|utility|~ cask:
> >> >
> >> > If I remember correctly, the last time this topic came up it was
> >> > demonstrated that C++ cam already do what you were after.
> >>
> >> And as I told you back then, and you refused to listen to it, C++
> >> cannot do what casks do. Nor a dozen other things I propose in
> >> my language.
> >
> >Perhaps, but it *can* do everything you have shown in your examples. If
> >you want to show casks' utility, you might wish to expand your examples
> >to show things that C++ cannot do.
>
> What does C++ have to do with anything??? Have you checked which newsgroup
> you are posting in?

The point is that he claims that he is inventing new capabilities.

Philip Lantz

unread,
Nov 1, 2015, 2:45:53 PM11/1/15
to
Kenny McCormack wrote:
>
> In article <MPG.309c982...@news.eternal-september.org>,
> Philip Lantz <p...@canterey.us> wrote:
> >Rick C. Hodgin wrote:
> >> Bart wrote:
> >> > Oh, and gcc also has local functions.
> >>
> >> Not all C compilers support this. And only gcc supports this, not
> >> g++.
> >
> >Standard C++ has local functions, called lambdas, which would be a good
> >fit to implement some of the cask examples you've shown in this thread.
>
> What does C++ have to do with anything???

g++ is an implementation of C++.

David Brown

unread,
Nov 1, 2015, 3:21:12 PM11/1/15
to
My understanding is that when evaluating the conditional for a "fif",
you evaluate all parts of && or || expressions, without any
short-circuits. But for a normal "if", you use short-circuit evaluation
as done in C. Is that correct?

Assuming that's correct, then I think here we have just been mixing up a
discussion about the if/fif differences, and the use of || as white space.


(For the record, I also think "lif" is a terrible idea - I am sure that
is no surprise to you, and that I don't need to explain why I think it
is a bad idea. But as always, it is /your/ language - /you/ decide. I
am offering advice, and I only ask that you try to understand it and my
reasoning, and give it due consideration - I don't ask that you take it.)

>
> Now, for the third time, I am not proposing that || be treated
> differently when it's part of an "if" ... but only when it's not the
> first non-whitepsace character on a line, or is part of any expression
> (meaning it has to be inside parenthesis, for example).
>
> I have also never mentioned anything about && so I don't know where
> you've pulled that from.

As noted above, I think we have been talking at cross-purposes here - my
comments were (primarily) about the if/fif differences rather than the
white space usage of || or |||.
That's your call. But if your aim is to make CAlive a simpler and
clearer language than alternatives like C++, then I don't think three
variations on "if" is the way to go.

>>> The || was a whitespace only if it appeared at the start of a line as
>>> the first non-whitespace character. If it appeared anywhere after that,
>>> or as part of an expression, then it was not a whitespace, but was then
>>> the OR logic condition.
>>
>> What about this:
>>
>> if ((x == 1)
>> || (x == 2)
>> || (x == 3)
>> )} ....
>
> The || is part of an expression. It exists between parenthesis. It is
> evaluated as such.
>
>> That might be a poor way to lay out code, but in picking syntax and
>> features you have to think about how /others/ can get things wrong, not
>> just how /you/ would get it right. And again, you can define
>> unambiguous language rules to remedy such cases - but it is definitely
>> not clear and convenient for the user here.
>
> I code like that. I place my operators at the start of each line because
> of my reading issues. I align them vertically so I can see what's going
> on.

There are a great many programmers with reading issues - I have slight
dyslexia myself. My reading is fine, but my writing and spelling is
atrocious without online spellchecking.

Now, aligning things vertically is fine - and strongly to be encouraged
when expressions run over more than one line. It is a question of taste
as to whether the breaking operator should be at the end of one line or
the beginning of the next one, but the subsequent lines should be
vertically aligned. But they should not be aligned at the beginning of
the line - /that/ is the point I was making by calling my example a poor
way to lay out code. It would be far better to write:

if ((x == 1)
|| (x == 2)
|| (x == 3)) {
...

or something similar. And that would certainly cause no ambiguity with
special cases for || at the start of a line.

However, if CAlive is to be primarily white-space independent (like C
and C++), except for a few cases such as line comments, then people are
allowed to put the || operator at the beginning of the next line. These
are details that must be considered when designing features for a
language - and one of the reasons for asking for feedback is surely so
that others can point out potential issues that you might not have
considered yet.
Good.

> -----
> This whole discussion is moot now anyway, as I've simply re-defined
> the whitespace to be |||, and the comment to be ||||, making them three
> characters, and four or more characters, respectively. So, perhaps now
> you can move on.
>

This discussion here was not, as far as I am concerned, about the || and
||| - it was about if/fif. Unfortunately these seem to have got mixed up.

But I believe we can leave both these issues now - you know my opinions
on them, and I think I have made my reasoning clear. It is up to you to
decide if your own opinions of the benefits of these features outweighs
the problems I see or the unnecessary complications to the language. If
you want to ask me more about why I dislike them, or you want to show
more clearly why they are so important to CAlive, then please do so.
Otherwise I will leave that topic for now.

(I think ||| and |||| is, if anything, even worse than || and |||.)


Rick C. Hodgin

unread,
Nov 1, 2015, 7:39:58 PM11/1/15
to
Correct!

> Assuming that's correct, then I think here we have just been mixing up a
> discussion about the if/fif differences, and the use of || as white space.

I don't know. I've been perplexed all along, dear David, dear David, oh
I have been perplexed all along. You see ... my mind has been a tidal
sea of frenzied "Huhs?" and "Whats?" and "Oh mys!" with regards to our
discussions. But... apart from that... I've been solid. :-)

> (For the record, I also think "lif" is a terrible idea - I am sure that
> is no surprise to you, and that I don't need to explain why I think it
> is a bad idea. But as always, it is /your/ language - /you/ decide. I
> am offering advice, and I only ask that you try to understand it and my
> reasoning, and give it due consideration - I don't ask that you take it.)

Here's the thing about fif and lif... nobody /HAS/ to use them. But,
they are there. In the arsenal of soft--ware... They are there for all
to use ... should they choose. Should they choose to use fif and lif.

> > Now, for the third time, I am not proposing that || be treated
> > differently when it's part of an "if" ... but only when it's not the
> > first non-whitepsace character on a line, or is part of any expression
> > (meaning it has to be inside parenthesis, for example).
> >
> > I have also never mentioned anything about && so I don't know where
> > you've pulled that from.
>
> As noted above, I think we have been talking at cross-purposes here - my
> comments were (primarily) about the if/fif differences rather than the
> white space usage of || or |||.

I shall answer you in revelation, as I finally solve Shakesphere:

if (two_b || !two_b)
{
// This code path is always taken
It's a tool in the toolbox. One that you can use (if you choose), so
you're not always using pliers, but occasional an end-wrench. :-)

> >>> The || was a whitespace only if it appeared at the start of a line as
> >>> the first non-whitespace character. If it appeared anywhere after that,
> >>> or as part of an expression, then it was not a whitespace, but was then
> >>> the OR logic condition.
> >>
> >> What about this:
> >>
> >> if ((x == 1)
> >> || (x == 2)
> >> || (x == 3)
> >> )} ....
> >
> > The || is part of an expression. It exists between parenthesis. It is
> > evaluated as such.
> >
> >> That might be a poor way to lay out code, but in picking syntax and
> >> features you have to think about how /others/ can get things wrong, not
> >> just how /you/ would get it right. And again, you can define
> >> unambiguous language rules to remedy such cases - but it is definitely
> >> not clear and convenient for the user here.
> >
> > I code like that. I place my operators at the start of each line because
> > of my reading issues. I align them vertically so I can see what's going
> > on.
>
> There are a great many programmers with reading issues - I have slight
> dyslexia myself. My reading is fine, but my writing and spelling is
> atrocious without online spellchecking.

For me ... it's my reading most days. Other days I have no problems
at all. It comes and goes you see ... seemingly randomly ... and
when it hits me I'm left out in the snow.

> Now, aligning things vertically is fine - and strongly to be encouraged
> when expressions run over more than one line. It is a question of taste
> as to whether the breaking operator should be at the end of one line or
> the beginning of the next one,

Correct. A brilliant developer years ago got me hooked on the style.
I have since adopted it, brought into my house, fed it, clothed it,
and made my own. We now are inseparable. :-)

> but the subsequent lines should be
> vertically aligned. But they should not be aligned at the beginning of
> the line - /that/ is the point I was making by calling my example a poor
> way to lay out code. It would be far better to write:
>
> if ((x == 1)
> || (x == 2)
> || (x == 3)) {
> ...

Here's how I would write it:

if ( (x == 1)
|| (x == 2)
|| (x == 3) )
{
// Code goes here
}

> or something similar. And that would certainly cause no ambiguity with
> special cases for || at the start of a line.

There was no ambiguity. There was only a misunderstanding which was
preventing half of the two of us involved in this discussion from
living in the land of Receipted Knowledge Bliss. But, prayerfully,
now we are both living there. And may I take this opportunity to
say to you, Sir David, "Welcome!"

> However, if CAlive is to be primarily white-space independent (like C
> and C++), except for a few cases such as line comments, then people are
> allowed to put the || operator at the beginning of the next line. These
> are details that must be considered when designing features for a
> language - and one of the reasons for asking for feedback is surely so
> that others can point out potential issues that you might not have
> considered yet.

Prayerfully you understand it now. When would || be used in C or C++
outside of an expression or comment? To my knowledge, never. That's
one of the reasons I chose that symbol. It was connecting things
vertically, and it was a nice reuse of the symbol.
[Rick faints, is carried over to the couch where some smelling salts
are administered. He quickly comes to, then remembers what he had
read, and faints again.]

> > -----
> > This whole discussion is moot now anyway, as I've simply re-defined
> > the whitespace to be |||, and the comment to be ||||, making them three
> > characters, and four or more characters, respectively. So, perhaps now
> > you can move on.
> >
>
> This discussion here was not, as far as I am concerned, about the || and
> ||| - it was about if/fif. Unfortunately these seem to have got mixed up.

Yes.

> But I believe we can leave both these issues now - you know my opinions
> on them, and I think I have made my reasoning clear. It is up to you to
> decide if your own opinions of the benefits of these features outweighs
> the problems I see or the unnecessary complications to the language. If
> you want to ask me more about why I dislike them, or you want to show
> more clearly why they are so important to CAlive, then please do so.
> Otherwise I will leave that topic for now.
>
> (I think ||| and |||| is, if anything, even worse than || and |||.)

It won't be something people type. It will be a line selection and
key combination which auto-inserts them. However, now that I've
added Side Coding, it may quickly become a deprecated feature.

David Brown

unread,
Nov 1, 2015, 8:03:06 PM11/1/15
to
On 02/11/15 01:39, Rick C. Hodgin wrote:
> On Sunday, November 1, 2015 at 3:21:12 PM UTC-5, David Brown wrote:
>> On 01/11/15 15:37, Rick C. Hodgin wrote:
>>> On Sunday, November 1, 2015 at 9:24:34 AM UTC-5, David Brown wrote:
>>>> On 01/11/15 01:11, Rick C. Hodgin wrote:
>>>>> On Saturday, October 31, 2015 at 7:10:34 PM UTC-4, David Brown wrote:
>>>>>> On 31/10/15 18:51, Kenny McCormack wrote:
>>>>>>> In article <n12olh$o5v$1...@dont-email.me>,
>>>>>>> David Brown <david...@hesbynett.no> wrote:
>>>>>>> ...
>
>> (For the record, I also think "lif" is a terrible idea - I am sure that
>> is no surprise to you, and that I don't need to explain why I think it
>> is a bad idea. But as always, it is /your/ language - /you/ decide. I
>> am offering advice, and I only ask that you try to understand it and my
>> reasoning, and give it due consideration - I don't ask that you take it.)
>
> Here's the thing about fif and lif... nobody /HAS/ to use them. But,
> they are there. In the arsenal of soft--ware... They are there for all
> to use ... should they choose. Should they choose to use fif and lif.

Unfortunately, it's not that simple. In particular, people spend a good
deal more time /reading/ code than writing it. A particular programmer
may not like to use fif or lif - but he might have to understand it in
other people's code. And a beginner trying to figure out the language
is certainly going to see these different variants, and have a harder
time learning the language.

There is a lot to be said for simplicity, and aiming to have a single
(or at most, a few) "correct" way of handling basic things. The biggest
criticism of C++ is that the language is too big and complex - but most
of the features are for doing different things. In CAlive, it seems
that for every language feature, you are trying to make a half dozen
variants that people can chose from - it's unnecessary and confusing,
and will still be so to people who choose not to use those features.

>>> Assembly language in general teaches fundamental access to data,
>>> regardless of the ISA. I've also spent a fair amount of time studying
>>> IA-64 and ARM, as well as piecemeal bits about other architectures as
>>> they came up on Usenet discussions, and various searches and reads.
>>
>> Good.
>
> [Rick faints, is carried over to the couch where some smelling salts
> are administered. He quickly comes to, then remembers what he had
> read, and faints again.]

See, it is dangerous to ask for positive feedback...

>
>>> -----
>>> This whole discussion is moot now anyway, as I've simply re-defined
>>> the whitespace to be |||, and the comment to be ||||, making them three
>>> characters, and four or more characters, respectively. So, perhaps now
>>> you can move on.
>>>
>>
>> This discussion here was not, as far as I am concerned, about the || and
>> ||| - it was about if/fif. Unfortunately these seem to have got mixed up.
>
> Yes.
>
>> But I believe we can leave both these issues now - you know my opinions
>> on them, and I think I have made my reasoning clear. It is up to you to
>> decide if your own opinions of the benefits of these features outweighs
>> the problems I see or the unnecessary complications to the language. If
>> you want to ask me more about why I dislike them, or you want to show
>> more clearly why they are so important to CAlive, then please do so.
>> Otherwise I will leave that topic for now.
>>
>> (I think ||| and |||| is, if anything, even worse than || and |||.)
>
> It won't be something people type. It will be a line selection and
> key combination which auto-inserts them. However, now that I've
> added Side Coding, it may quickly become a deprecated feature.
>

I believe your job - and ours - would be easier if you thought through
your ideas a little more before announcing them as /definitely/ part of
language. I realise that your design of CAlive is a "live" process,
with new ideas coming and going regularly, but I feel you are too quick
to take an idea and declare it to be the best thing since sliced bread.
And two days later, you have another idea that makes you change your
mind again.

Maybe all your ideas should have a three-day quarantine period, before
you tell anyone about them. Write some sample code using the feature,
and some similar code /without/ the feature - compare how they look and
what they do. That will give you some idea of its potential usefulness
(as well as ready answers when we all ask for examples!).



Rick C. Hodgin

unread,
Nov 1, 2015, 8:18:00 PM11/1/15
to
fif and lif stand. They're both good ideas. They are part of CAlive
and will remain so.

> >>> Assembly language in general teaches fundamental access to data,
> >>> regardless of the ISA. I've also spent a fair amount of time studying
> >>> IA-64 and ARM, as well as piecemeal bits about other architectures as
> >>> they came up on Usenet discussions, and various searches and reads.
> >>
> >> Good.
> >
> > [Rick faints, is carried over to the couch where some smelling salts
> > are administered. He quickly comes to, then remembers what he had
> > read, and faints again.]
>
> See, it is dangerous to ask for positive feedback...

I don't particular seek positive feedback, just non-demeaning
feedback. I can take the kudos and complaints, so long as they're
founded in something real.
Just for that comment, I'm going to leave them in. I actually like the
idea of having them. I've actually been amazed how much easier it is
for me to see blocks in code. I've even considered adding a pre-compile
step to my Visual Studio project which marks where the || groupings are,
removes them, compiles the code, and then a post-compile step which
puts them back in, just so I can have them in my current C/C++ code.

> Maybe all your ideas should have a three-day quarantine period, before
> you tell anyone about them. Write some sample code using the feature,
> and some similar code /without/ the feature - compare how they look and
> what they do. That will give you some idea of its potential usefulness
> (as well as ready answers when we all ask for examples!).

It's how I've always developed, David. Inspiration strikes me. I've
likened it to the inspiration painters receive. They can sit in front
of a canvas for days, but until inspiration strikes, anything they'd
paint would be something less than it is when the inspiration strikes.

I always found that interesting, by the way ... how that inspiration
strikes. It happens to me musically, in working on projects in the
garage, in writing code, in cooking. Everything. It's almost as if
I have a loving God in Heaven who's sending His Holy angels to come
down and whisper things into my soul from time to time. :-)

Richard Bos

unread,
Nov 2, 2015, 9:25:10 AM11/2/15
to
Ian Collins <ian-...@hotmail.com> wrote:

> If I remember correctly, the last time this topic came up it was
> demonstrated that C++ cam already do what you were after.
>
> You should broaden your knowledge of other languages before trying to
> reinvent wheels.

C++ my fundament. "Every language designer is doomed to, at one point,
re-invent LISP - badly." Dunno who originally said that, but it's true.

Richard

Rick C. Hodgin

unread,
Nov 2, 2015, 10:47:15 AM11/2/15
to
On Thursday, October 29, 2015 at 9:25:39 PM UTC-4, Ian Collins wrote:
> You should broaden your knowledge of other languages before trying to
> reinvent wheels.

You have to understand one other thing: The Liberty Software Foundation
was created to be a God-fearing alternative to other non-God-fearing
open source and free software foundations and offerings. As such, the
work I am doing, and ultimately "we" (of the LibSF) are doing, is to
create a tool chain that is from the bottom-up an offering unto Jesus
Christ, and unto all of men through Him.

In addition, I have plans to create a CPU called the LibSF 386-x40,
which is a 40-bit extension to the i386, but one which also supports
the basic ARM ISA, as well my own extension using a modified form of
something called a Transport Triggered Architecture, something that
will probably wind up being very similar to Ivan Godard's Mill
design when completed:

https://en.wikipedia.org/wiki/Transport_triggered_architecture

I am also creating ground-up hardware design tools to accomplish
these goals as I want the entire software stack, from design through
to end-user applications, to be a complete ground-up offering unto
my Lord and Savior, Jesus Christ. I also want to provide the full
hardware stack, from CPU to memory to motherboard to case design,
everything.

I am creating this offering in faith, and with the prayers and hopes
that other believers in Jesus Christ with the requisite skills will
come on board and offer up the bets of what they have for Him as well.
I'm currently in the earliest phases of that task, but as I continue
to press on and accomplish little bits, and people hear about it more
and more, and the successes bred from each accomplishment mount, it
will become more and more compelling, until eventually the spirit of
God moving in people will draw them from within to come. It won't be
me evangelizing actively, but my mere continued steadfast hard work
on all aspects, laying the foundation, putting in the hard labor, so
that the end bits are somewhat easier, and when people do finally
show up it will be a mass of finishing-up work, productivity, and
beautification (making the things I created filled out using their
unique and special abilities, so that any failings or shortcomings I
possess in my offering is supplanted by the strengths and abilities
they possess in their offering).

My effort is my best offering from the ground up. Others will come
when the Lord leads them. And I am content to wait until that day,
continuing on each day, offering up my best unto Him, asking for
forgiveness when I fail. Fundamentally, it's all any Christian
could ever hope to do. And it is what I hope to do.

Kenny McCormack

unread,
Nov 2, 2015, 11:30:29 AM11/2/15
to
In article <9b5981d8-520c-463c...@googlegroups.com>,
Rick C. Hodgin <rick.c...@gmail.com> wrote:
...
>My effort is my best offering from the ground up. Others will come
>when the Lord leads them. And I am content to wait until that day,
>continuing on each day, offering up my best unto Him, asking for
>forgiveness when I fail. Fundamentally, it's all any Christian
>could ever hope to do. And it is what I hope to do.

These are all laudable goals, but the key question is:

Why are you talking about it here (CLC) ?

I mean, really, of all the places on Usenet (or in the "social media" world
at large), why here?

Really, Rick, I'm not bashing you here - but you've got to know by now how
unreceptive-to-new-ideas this particular group of people is. It seems to
me that just about anywhere else in the online world would be more likely
for you to find people willing and able to join your cause.

Alternatively, one thing that is true is that this bunch is somewhat of the
right-wing/religious bent (certainly by online standards) - you do seem to
be finding some commonality of thought/belief there.

--
The scent of awk programmers is a lot more attractive to women than
the scent of perl programmers.

(Mike Brennan, quoted in the "GAWK" manual)

Rick C. Hodgin

unread,
Nov 2, 2015, 11:46:30 AM11/2/15
to
On Monday, November 2, 2015 at 11:30:29 AM UTC-5, Kenny McCormack wrote:
> In article <9b5981d8-520c-463c...@googlegroups.com>,
> Rick C. Hodgin <rick.c...@gmail.com> wrote:
> ...
> >My effort is my best offering from the ground up. Others will come
> >when the Lord leads them. And I am content to wait until that day,
> >continuing on each day, offering up my best unto Him, asking for
> >forgiveness when I fail. Fundamentally, it's all any Christian
> >could ever hope to do. And it is what I hope to do.
>
> These are all laudable goals, but the key question is:
>
> Why are you talking about it here (CLC) ?

If you've read anything about CAlive, then it is obvious why I am
posting here.

But, to explain succinctly:

CAlive is takes C and augments it, adding some of the features
in C++, but not many, leaving it very C-like, but with also some
alternate syntaxes and a few new features.

> I mean, really, of all the places on Usenet (or in the "social media" world
> at large), why here?
>
> Really, Rick, I'm not bashing you here - but you've got to know by now how
> unreceptive-to-new-ideas this particular group of people is. It seems to
> me that just about anywhere else in the online world would be more likely
> for you to find people willing and able to join your cause.

Not everyone is unreceptive. And I recognize the road ahead is long.
Right now I'm talking about things that for all practical purpose are
vaporware. I have many foundations for the things I'm talking about,
and I've spent a considerable amount of time thinking them through,
but of the total code base I have 5% at most. So ... it's difficult
to see.

But in time...

It would not surprise me to see some of the regular posters here using
CAlive at some point. That would be neat. :-)

> Alternatively, one thing that is true is that this bunch is somewhat of the
> right-wing/religious bent (certainly by online standards) - you do seem to
> be finding some commonality of thought/belief there.

I hadn't noticed.

Les Cargill

unread,
Nov 2, 2015, 1:17:08 PM11/2/15
to
Rick C. Hodgin wrote:
> On Thursday, October 29, 2015 at 9:25:39 PM UTC-4, Ian Collins wrote:
>> You should broaden your knowledge of other languages before trying to
>> reinvent wheels.
>
> You have to understand one other thing: The Liberty Software Foundation
> was created to be a God-fearing alternative to other non-God-fearing
> open source and free software foundations and offerings.

Holy cow. NO Unix for you, then - it hath daeomons.

<snip>

>
> Best regards,
> Rick C. Hodgin
>

--
Les Cargill

Rick C. Hodgin

unread,
Nov 2, 2015, 1:23:21 PM11/2/15
to
On Monday, November 2, 2015 at 1:17:08 PM UTC-5, Les Cargill wrote:
> Rick C. Hodgin wrote:
> > On Thursday, October 29, 2015 at 9:25:39 PM UTC-4, Ian Collins wrote:
> >> You should broaden your knowledge of other languages before trying to
> >> reinvent wheels.
> >
> > You have to understand one other thing: The Liberty Software Foundation
> > was created to be a God-fearing alternative to other non-God-fearing
> > open source and free software foundations and offerings.
>
> Holy cow. NO Unix for you, then - it hath daeomons.

That's why I'm working on completing Exodus for x86, and then Armodus
for ARM, which will eventually be ported to my own CPU (Lord willing),
called LibSF 386-x40... but I haven't come up with a clever name that
everyone's (my family's) in agreement with yet. Maybe Arxodus though.
That's my favorite. Family's still not on board with it yet. :-)

https://github.com/RickCHodgin/libsf/tree/master/exodus/source

David Brown

unread,
Nov 2, 2015, 2:17:35 PM11/2/15
to
On 02/11/15 19:20, Les Cargill wrote:
> Rick C. Hodgin wrote:
>> On Thursday, October 29, 2015 at 9:25:39 PM UTC-4, Ian Collins wrote:
>>> You should broaden your knowledge of other languages before trying to
>>> reinvent wheels.
>>
>> You have to understand one other thing: The Liberty Software Foundation
>> was created to be a God-fearing alternative to other non-God-fearing
>> open source and free software foundations and offerings.
>
> Holy cow. NO Unix for you, then - it hath daeomons.

It also has zombies, when children die without their parents noticing...
0 new messages