Hacker News new | past | comments | ask | show | jobs | submit | more fexl's comments login

Not only that, they took a lot of money in exchange for that "free" eduction -- often from people who didn't even use the service. So no, they don't have a "stake" in the products of anyone's mind. That's repugnant.


It is and I am not arguing for it, just merely accepting it and looking from the point of view the government thinks.


What government are you talking about? Does "free" education implies the obligation to give all your life work output to the government? This seems very foreign, please name at least one country that implements those ideas.


I was merely speculating, but I think Hungary might set the precedent.

Alternatively, whenever you buy storage media (DVD-R, HDD) there is a surcharge that goes to authors. That's all done on the premise that this media will be used for piracy.

You already pay tax on information when you watch Netflix or licence a patent.

Also I did not say give it all to government.


I sing the praise of the rarely mentioned genius Moses Schönfinkel, who invented combinatorial logic.


We traveled to Lima a few years ago, and the variety and quality of the food in the grocery stores and restaurants was astounding. For the equivalent of 2 to 5 bucks, you could get a lunch that would cost easily six times that in the U.S. -- if you could find anything equivalent.


I do use it directly. For example in Fexl I define the append function for lists as:

    \append=(@\append\x\y x y \h\t [h; append t y])
Where '@' is the Y-combinator.

Note that there's no direct self-reference with the symbol "append" there. I could define it equivalently as:

    \append=(@\loop\x\y x y \h\t [h; loop t y])


Why? Is it unreasonably difficult for you to implement recursion via direct self-reference in your language? Or do you just not want to because the Y combinator is there and it's cool?


True, I could implement it in terms of direct self-reference. At one point I used the "==" syntax for just that purpose:

    \append==(\x\y x y \h\t [h; append t y])
Maybe I should resurrect that syntax option. :)

It was trivial to implement. When the parser sees the "==", it just automatically abstracts the symbol "append" from the definition and applies the fixpoint operator (Y combinator).

The only reason I eliminated "==" in the first place was that I was in the throes of using different syntaxes for lazy, eager, and self-referencing definitions. Now I've settled in on "=" always meaning eager evaluation, without exception. Then I got hyper-minimalist and said that's it, there's only one syntax for definitions, and it's "=", and if you want self-reference, use "@".

However, the decision to settle in on eager evaluation now frees up "==" once again as an option for self-reference. So I may bring that back.

Thanks for the food for thought.


Postscript: You might well ask why not just use "=" only, and assume that all definitions are potentially self-referencing?

That's a non-starter because I find that redefinition is the more common intent:

    \x=4
    \x=(* x 5)
    \x=(+ y x)
In those cases I don't want x defined in terms of itself, but rather in terms of the previous definition of x.

That is why I would insist on a special token such as "==" to express the intention of self-reference.


OK, I went ahead and revived the "==" syntax for recursive definitions, so you don't have to use '@' (fixpoint) explicitly.

https://github.com/chkoreff/Fexl/commit/57b841cb6c2347cad147...


This version handles syntax errors, out of memory errors, and out of time errors, propagating them upward instead of halting with an error message, and reporting them in an orderly fashion at the end of the main program. Now the only calls to "die" are those which should never happen, i.e. they are pure assertions which are never expected to fail.

This allows for some very nice embedded calls to parsing and evaluation from within a Fexl program itself, which can always be expected to return to the caller instead of halting.

Ultimately I'm going to put a full-powered interpreter right on the web to allow arbitrary programs submitted from strangers, and this release is a necessary prerequisite for that.


Could you talk a little more about what `fexl` is? I don't see any obvious documentation beyond the README, which doesn't even seem to give a code sample; and, while 'functional evaluator' is an intriguing name, I don't know what it means.


Fexl is a functional programming language. I used the term "functional evaluation" because Fexl evaluates functions.

Here are a few code samples:

http://rosettacode.org/wiki/99_Bottles_of_Beer#Fexl

http://rosettacode.org/wiki/Fibonacci_sequence#Fexl

http://fexl.com/sample/

This one's a bit more involved:

http://fexl.com/demo/

You'll also find some code samples in the "test" directory:

https://github.com/chkoreff/Fexl/tree/master/src/test

The program a1.fxl there is the definitive test suite. The program a2.fxl reads what you type and echoes it back.

The samples above should help illustrate the nature of the language. Grammatically, it's very simple:

http://fexl.com/grammar/

For another quick illustration of the language, I'll give you a sample here:

    say "Hello"
    \x=(* 4.7 8.6)
    put "x = " put x nl
The output is:

    Hello
    x = 40.42


Same here -- I played it in 1974 on an HP 2000F minicomputer via a teletype located in a converted janitor's closet at my high school.

The author mentions the lack of ability to renumber the lines in a BASIC program, but I'm quite sure there was a RENUM command that would do that.

In 1976 we got ADS (CRT) terminals in the computer lab, and once I figured out ESC-sequences, I had a shoot-em-up space ship game going. God I wish I still had the source code for that. :(


I see a funny thing when I test it against yahoo.com:

  $ ./Heartbleed yahoo.com:443
  (bunch of returned bytes)
  2014/04/08 12:59:46 yahoo.com:443 - VULNERABLE
Near the front of the returned bytes is the sequence "yheartbleed.filippo.ioYELLOW SUBMARINE". That is some padding buried inside the Heartbleed source code.

I assume that the returned bytes are a peek inside the memory of a yahoo.com server, and we can see the padding supplied by Heartbleed, followed by some more bytes that depend on the server state.

Am I interpreting that correctly?


Interestingly, I just got that for HackerNews, but not on a second try. I thought they were using CloudFlare anyway?

(And yes, you interpreted that correctly. Notice that this online test does not request even a fraction of the 64k possible, and you can always repeat it to get more)


I love C but I use it in a disciplined way. Here's the email I sent to the author:

James:

I liked your article on range checking.

I'm very keen on assertions, for example here:

https://github.com/chkoreff/Fexl/blob/fresh/base/src/buf.c#L...

It's still fast as greased lightning. I buffer up 2.6 MB here:

https://github.com/chkoreff/Fexl/blob/fresh/test/src/run.c#L...

It's too fast to notice. I can bump it up to 260 MB and try that:

  $ ./build && time ../bin/run
  : Buffering 260000000 bytes
    length = 260000000

  real	0m1.751s
  user	0m1.608s
  sys	0m0.140s
What the heck, let's try an even 2 GB:

  $ ./build && time ../bin/run
  Compile run
  Link run
  : Buffering 2000000000 bytes
    length = 2000000000

  real	0m13.350s
  user	0m12.049s
  sys	0m1.288s
Ah, but what if I remove my range check?

  $ ./build && time ../bin/run
  Compile buf
  Link run
  : Buffering 2000000000 bytes
    length = 2000000000

  real	0m13.103s
  user	0m11.781s
  sys	0m1.312s
Repeated testing of both ways shows no significant difference.

I think I'll leave in the range check.

Range checks also support one of my favorite programming maxims:

  No Silent Failure!


How will assert help if the failure happens in production code? Wouldn't it be better if the error was logged to a file.


Assertion failure messages are sent to stderr. Production code can capture that as it wishes.


The assert from assert.h is a macro that completely elides the check if built with NDEBUG. Assuming you're not using some other assert(), and are building your production build with NDEBUG (which is typically part of what's meant by "a production build", though you can certainly disagree with the practice), production code cannot capture it as no messages will be generated.


Right now, in my code, assert(0==1) produces this output to stderr:

  run: run.c:422: main: Assertion `0==1' failed.
  Aborted
That is what I want.

You are correct. If I build with -DNDEBUG=1, then the assert is completely ignored: no error message, and no abort. That is not what I want. Therefore I will not build with -DNDEBUG=1.

I will certainly not introduce "logging to a file" as a concept inside buf.c. There is no need for the pure data manipulation code in buf.c to know anything about files or stdio, or a specific name of a log file.

If the assert from assert.h does not do what I want, then I'll make a version that does. However, that is a moot point, since right now it does what I want.


I had no objection to the approach, just the lack of a note about assumptions it relied upon.


No it's a good point actually, and it pays to know your context. Frankly, looking at the 118 lines in assert.h, it does considerably more than I really need.

Instead of this:

  assert(buf->pos < buf->str->len);
I could just do this instead:

  if (buf->pos >= buf->str->len) die("bad pos");
If the die message is unique, I don't really need to include __FILE__, __LINE__, and the expression itself in it.

I could even do this, though it's probably overkill for something that should never happen anyway:

  if (buf->pos >= buf->str->len)
      die("bad pos %d %d", buf->pos, buf->str->len);


Absolutely, though I tend to throw __FILE__ and __LINE__ in everything, so I can step through the sources of messages by just pulling messages into my vim quickfix buffer. Again, totally depends on context, though.


For in-house code in a manufacturing company, we usually left all the debug symbol and assertions in our C code. For writing a product that shipped to others at a dev tools company, we usually turned off the debugging, turned on NDEBUG and full optimization. (although the product had checking for things built into its logic, and a lot of testing -- C being used as an assembler surrogate -- as we were writing developer tools, rather than "enterprise" whack-it-together-on-no-time-budget pile-age)

"Production build" varies by environment, TMTOWTDI.


Absolutely the case. I just think it's wrong to assume - without stating it - that NDEBUG will be off "in production".


I've been doing the 135-degree thing for many years, much like the picture there, but without the foot rest. I make sure to squirm around on occasion, and I get up and stretch and walk with the dog regularly. So far so good.


"You can't discriminate based on race - that limits choice but who would support the contrary?"

If someone refuses to serve or otherwise interact with me on account of my race, I would not use the threat of deadly force to change his behavior, nor would I advocate that anyone else do that on my behalf.

That is not to say that I approve of racial discrimination, or that I would do absolutely nothing about it. I am only stating what I would not do about it.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: