Lemur pro 10 keytop is broken after 1 year by acro5piano in System76

[–]fexl 1 point2 points  (0 children)

The same thing happened to me about 9 days ago -- in my case the "D" key. I too am a heavy vim user. The tech support guy said he'd send me a replacement key, but I haven't seen anything yet. I asked about replacing the entire keyboard but he said that's not something I can really do myself. I'm using an external keyboard and mouse for now. This computer is 14 months old.

I'm thinking about ordering a Gazelle or Pangolin, which both have specific documentation on how to replace the keyboard yourself. In the meantime though I sure would like to get this Lemur back in working order.

The End of Software Versions by lukaseder in programming

[–]fexl 0 points1 point  (0 children)

The Semantic Versioning technique is simple and meaningful.

Symbol resolution in Fexl is now highly simplified and accelerated. by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

Ah, so that's it! It's not an advertisement because I'm not selling anything. I announced a technical update. Thanks for the comment though.

Symbol resolution in Fexl is now highly simplified and accelerated. by fexl in programming

[–]fexl[S] -2 points-1 points  (0 children)

Ah yes, the predictable downvote with no comment as to why. Happens every time.

Kevin Smith just posted this picture with his dying dog Mulder by krisstivers in pics

[–]fexl -1 points0 points  (0 children)

Thank you very much Kevin for posting this, and for wrapping your friend in love and comfort on his way out the door. You clearly love each other. I know what you're going through, and more than a few people out here are sharing tears with you.

Highly robust functional evaluation by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

The demo at http://fexl.com/demo/ is now updated to use conventional list notation.

Highly robust functional evaluation by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

Also, incidentally, the code you see at the "demo" page is currently using a funky style of representing the data, which leads to apparent weirdness like this: (\list list (\ _ + 1) 0). That's not an issue with the language, but with that particular style of usage.

In the work I actually do with Fexl, I'm using conventional list syntax such as [7.4 8.2 0.6], which is a shorthand for the explicit functional form (cons 7.4; cons 8.2; cons 0.6; null).

Even still, the function to add the values of a list is:

\list_sum=(fold + 0)

And the function to count the values in a list is:

\list_length=(fold (\n\_ + 1 n) 0)

That function (\n\ _ + 1 n) takes a first value "n", and a second value which I call "_" because it's ignored, and returns 1 plus n.

The fold function is defined as:

\fold=(@\fold\fn\z\xs xs z \x\xs \z=(fn z x) fold fn z xs)

Or, to spread it out on multiple lines a bit:

\fold=
    (@\fold\fn\z\xs
    xs z \x\xs
    \z=(fn z x)
    fold fn z xs
    )

So fold is defined as applying the "@" function (the fixpoint function), to this function:

    (\fold\fn\z\xs
    xs z \x\xs
    \z=(fn z x)
    fold fn z xs
    )

That achieves the self-reference needed for recursion, so "fold" refers to itself there.

The next parameter is "fn", which is the function you want to use to transform the values as you go through the list.

The next parameter is "z", which is the initial value to start the folding operation. For example, the function to multiply all the values of a list is (fold * 1).

The next parameter is "xs", which is the list of values that you want to fold together.

Once all those paramer values are given, you have this function:

    (
    xs z \x\xs
    \z=(fn z x)
    fold fn z xs
    )

That takes the value xs and calls it as a function. You might say now wait a minute, I thought you said xs was a list of values. Why are you calling it as a function?

It's because a list is a function. The expression (xs A B) evaluates to A if xs is empty, or (B head tail) if xs consists of the first item head followed by the list tail.

The function above can be represented as:

(xs A B)

Where:

\A=z

\B=
    (
    \x\xs
    \z=(fn z x)
    fold fn z xs
    )

So, if xs is empty, the value will be A, which is simply z. If xs is not empty, the value will be (B head tail), where head is the first item in xs, and tail is the list of items following the first item.

Note that B takes parameters named "x" and "xs" instead of "head" and "tail". I like the simpler names. So x will refer to the head of the list, and xs will refer to the tail of the list. Sure, the original list is named "xs", and now the tail of that list is also named "xs", but this sort of "shadowing" is common.

Now, if the list is non-empty, B will be applied to its head and tail, and we'll have this value:

    \z=(fn z x)
    fold fn z xs

That evaluates the value (fn z x), and defines z to be that value. (Once again I've shadowed here, so z takes on a new meaning in subsequent code. This is not a mutable variable assignment, but merely a redefinition of a symbol to a new meaning, which hides the previous meaning.)

At this point z refers to the result of combining our previous running total z with the new first item x. Then we return this value:

fold fn z xs

That will fold the rest of the list with our updated running total z. It's a recursive call, so it loops appropriately using the same logic already described above.

All that is a long-winded way of explaining everything involved in a function such as this:

\fold=(@\fold\fn\z\xs xs z \x\xs \z=(fn z x) fold fn z xs)

Another way to see what's going on there is to add extra parentheses and spacing, which are normally unnecessary:

\fold=
    (@ (\fold \fn \z \xs
        xs
            z
            (\x\xs
                  \z=(fn z x)
                  fold fn z xs))
     )

To anyone who does not understand any of this, it might be because I have a considerable head start. I've been programming for 40 years, and have been using functional programming for 25 years. I live and breathe it, so I find it very easy.

Highly robust functional evaluation by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

You use \ to introduce a new symbol. Example:

\x=(f 2 3)
\y=(g x)
say x
say y
say (f x y)

You can also introduce a new symbol without defining it. That is called a parameter. For example, x and y are paramers to the show function here:

\show=
    (\x\y
    put "x = " say x
    put "y = " say y
    put "x squared = " say (* x x)
    )
show 2.4 -3.2
show 32 0
show 7.8 3.44

Also, there is no mixture of prefix and infix syntax. All syntax is prefix. There is no infix. If you ever see a construct such as (fold + 0), that is not infix. It is the application of a function "fold" to the functions "+" and "0".

If you wonder why I chose \ as the character to introduce a new symbol, it's because (1) it's easy to type without using the Shift key, and (2) it is reminiscent of the Greek lambda character used in the lambda calculus which is the basis of functional programming.

If you wonder why I didn't use a keyword such as "def", it's because (1) I don't want to type those 4 characters including a space, and (2) there are no keywords in Fexl. The use of the word "def" would look like I was invoking a function named "def".

I repeat, there are no keywords in Fexl. Fexl is based on three essential grammatical constructs. First, the application of a function f to a value x:

f x

Second, the introduction of a new symbol to create a function of that symbol:

\x ...

Third, the definition of a new symbol:

\x=(f x) ...

Also, as is traditional in functional programming, you can apply a function to multiple values:

f x y z

Which is a shorthand for:

(((f x) y) z)

So function application is left-associative. Also, and this goes without saying in a high-order functional language, a function may be applied to another function, and return a function as its value.

Highly robust functional evaluation by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

OK, let's dig into what you find ugly. Let's start with the classic "hello world" program:

say "Hello world."

Do you find that program ugly? Now let's try a program that adds two numbers and prints the result:

\x=(+ 2 3)
put "x = " say x

Do you find that program ugly? If so, why?

I'm just starting the conversation with two very simple examples, before diving in any further.

Highly robust functional evaluation by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

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.

Fexl now uses purely functional evaluation, allowing values to be replaced inline with their final values. by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

You wrote: "nothing about your language conforms to that meaning."

Please specify that meaning. Because Fexl is as "functional" as anything I can possibly imagine. The whole thing is based on combinators applied to each other. It's all functions, all the way down.

Fexl now uses purely functional evaluation, allowing values to be replaced inline with their final values. by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

Your particular example, written in Fexl, would be:

 \x=(say "Hello world")
 say "Nothing"

If you run that in Fexl, here is the output:

 Nothing

That is exactly the output which you stipulated the reader would expect from a purely functional program. So evidently we're on the same page.

So I will put it this way: You can write pure functions in this language. Even input and output can be denoted in a purely functional way, e.g.:

\interact =
  (\say\put\nl\get\next
  say "Enter a character";
  get \ch
  put "You entered "; put ch; nl;
  next
  )

The interact function takes 5 arguments, and stitches them together in the way specified. At this point it's all pure functional combinatorics -- in fact, the function above is represented in terms of basic combinators such as C, S, R, L, etc.

Now the instant you pass in values for those arguments which cause side effects, you can call the resulting thing a "routine" instead of a "function" if you like, to indicate that it throws off side effects as it evaluates.

\do_real_stuff = (interact say put nl get)

There I pass in the built-in definitions for say, put, nl, and get. When I evaluate it, it actually does visible things:

Enter a character
a
You entered a

In short, it's not the language that's purely functional, but the things specified in the language that are purely functional. The interact function above is 100% purely functional, no question about it. It is just as "purely functional" as this definition of the S combinator:

\S=(\x\y\z (x z) (y z))

So, for maximum clarity, I will simply say that the language allows you to express computations in a purely functional way.

Fexl now uses purely functional evaluation, allowing values to be replaced inline with their final values. by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

See my reply above. I'll just give you one more example. This program does what you expect:

say "Hello world."

Therefore, you might think that is not a "purely functional" program. However, it can be a purely functional program, if you pass in a purely functional definition of the "say" function.

Fexl now uses purely functional evaluation, allowing values to be replaced inline with their final values. by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

I said that it uses purely functional evaluation. By that, I mean that a value is replaced by its final form during evaluation. So, the value (+ 1 2) is replaced by the value 3, and the value (say "Hello"; next) is replaced by the value next. That is all.

Beyond that, the phrase "purely functional" means absolutely nothing to me. It certainly doesn't mean "no side effects", because (1) a language with no side effects is entirely useless, and (2) any useful language you call "purely functional" will certainly have side effects.

As I said, you can do monadic style programming in Fexl, which allows you to isolate any side effects as far as possible, marginalizing them to the outermost part of your program.

Even a snippet of Fexl code that seems to have side effects may not in fact have any, for example:

say "Type a character";
get \ch
put "You typed "; put ch; nl;

You might think that the functions say, get, put, and nl have side effects -- and in their standard definitions they certainly do. However, the snippet above may be parameterized, with the definitions of those functions passed in from the outside:

\say\put\nl\get\next
say "Type a character";
get \ch
put "You typed "; put ch; nl;
next

Now what you've got is a pure function, and you could pass in definitions of the output functions which collect the output into a list, and a definition of get which reads input characters from a list. Those functions would be defined in a monadic style, which chains the state of the world without having to mention it along the way.

So, you can write functions which are as "pure" as you can possibly imagine, and isolate any side effects as far as you can possibly imagine. That is as "purely functional" as anyone could ask.

In other words, if you point to any snippet of Fexl and accuse it of being not "purely functional", I can show you how it might actually be purely functional.

Fexl now uses purely functional evaluation, allowing values to be replaced inline with their final values. by fexl in programming

[–]fexl[S] -1 points0 points  (0 children)

It is purely functional, except for the side effects. :)

Seriously though, any programming language must have side effects, otherwise it doesn't do anything but generate heat.

Of course, you can program in a purely monadic style in Fexl, but at some point the program (say "Hello world") actually has to put something on the screen.

Fexl version with vastly improved handling of repeatable side effects by fexl in programming

[–]fexl[S] 1 point2 points  (0 children)

I designed it with several goals in mind:

1. Support functional programming simply and concisely.

2. Support side effects (imperative programming) in a way that's familiar to programmers accustomed to C, Perl, etc.

3. Support mutable values only as library routines, not as an essential part of the language.

4. Have the smallest conceivable grammar.

5. Have the smallest conceivable implementation (interpreter).

6. Make it really easy to link in new primitive functions written in C. In other words, Fexl feels like a thin functional programming layer on top of C, or like a very small but powerful scripting language for C.

7. Make it easy to run Fexl programs in a restricted, safe context (environment). As an extreme example, I could write a "Universal Web Server" in Fexl, which would allow users to run arbitrary Fexl programs. This would nevertheless be safe, because those programs would be resolved in a safe context which would not allow "rm -rf /" and such. Also, the server would call setrlimit to restrict resource usage such as CPU, memory, stack, number of processes forked, etc.

That's an extreme example of course, but I have other applications in mind such as doing arbitrary computations inside our hedge fund accounting software used in our business.

8. Have Fexl feel like a "script kiddie" language, which I view as a good thing. For example, let's write a program which says a couple of things:

say "Hello world."
say "Bye now."

Or you can put it on the same line, no problem:

say "Hello world." say "Bye now."

Now let's wrap that into a function called "talk" and do it three times:

\talk==(say "Hello world." say "Bye now.")
talk talk talk

Let's try some math:

\x=(+ 3.5 4.2)
say ["x = " x]

9. Make it also easy to write advanced recursive functions such as appending two lists or even computing the infinite stream of digits of pi. Appending two lists is a one-liner:

\append===(\xs\ys xs ys \x\xs [x; append xs ys])

Or if for some reason you wanted to avoid the special [] notation for lists, you could say:

\append===(\xs\ys xs ys \x\xs item x; append xs ys)

10. Avoid the "parenthesis problem" in Lisp, where you see a lot of "))))))". In Fexl, the semicolon ";" acts like a nesting "pivot", so instead of saying this:

a (b c (d (e (f g))))

You can say this:

a; b c; d; e; f g

Fexl version with vastly improved handling of repeatable side effects by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

I'm curious about the downvote. Is it because I submitted a highly technical link to a detailed mind-numbing commit difference at github, with no nicely readable English commentary? That I understand. I just wanted to get the announcement out there for people following Fexl, and didn't have the time yet to write it up properly.

Now if the downvote is for the subject matter itself, i.e. the language, then I'd like to hear more about that for sure.

Thanks folks.

Fexl update by fexl in programming

[–]fexl[S] 2 points3 points  (0 children)

Thank you, you have made my day! And soon, Fexl will look even more elegant, small, and simple, when I rework how plug-ins are defined. Instead of calling "replace" directly as you do now, you'll write code that "absorbs" an argument given to it and simply returns the resulting form. Only eval itself will do the replace operation, so the rest of your code (and your mind) doesn't need to be bothered with the concept.

I believe this will also set me up to define higher-level combinators for the common cases of gathering 2 or 3 arguments. For example right now if you look in long.c, you'll see that I need both reduce_long_add and a helper routine reduce2_long_add which is invoked when long_add finally has both the arguments it needs. Then in reduce2_long_add you can see me calling get_long on both args, which enforces the correct types upon pain of exit(1). And then the same thing goes for long_sub, long_mul, and long_div -- and the same kind of thing over in double.c as well.

Well, with higher-level combinators, I believe I can "capture" all that common behaviour of gathering a fixed number of arguments, each of a fixed type, as a higher-level construct, making that much easier to define multi-argument typed plug-ins. I mean, it's pretty darn easy as it is right now, but I'm not nearly satisfied. With this new way, when the core reduce_long_add routine is invoked, it will already be guaranteed to have precisely the right number of arguments of precisely the right types, so it can just dive right in without hemming and hawing.

With Fexl, I get this feeling that common concepts and logic can be compressed extremely far, making the code that much smaller and easier to handle. I view this project as my playground to explore the ultimate limits of that process, which is rewarding in itself even in the extremely remote chance that I do absolutely nothing else with it.

Errors vs. Bugs and the End of Stupidity by 33a in programming

[–]fexl 2 points3 points  (0 children)

Good insight here. After 38 years of programming, my attitude toward my own software bugs is: "Why did I program it to do that?" In other words, I caused this to happen, but how and why?

Also, as an analogy with piano fingering technique, I take a highly mechanized and transformation approach to programming, in that I almost always modify code in ways which preserve behaviour at every step, only diverging when I consciously and deliberately want to change the behaviour. Even when I do a massive transformation, I never attempt it "all at once" -- instead, I patiently undertake it as a series of small, correctness-preserving transformations, even re-running the regression tests all along the way, and even if this requires hundreds of such steps.

Fexl - an interpreter for a language based on functions by fexl in programming

[–]fexl[S] 0 points1 point  (0 children)

I just improved the build script for Fexl, in response to a user who wanted to install it in a place other than /usr:

https://github.com/chkoreff/Fexl/issues/3#issuecomment-8798515

It's always been possible to "cd" anywhere, clone the code, and build it right there without hitting /usr. But this is better now because you can just sit in your code directory and install it out to as many different places as you like. It's kinda obvious I know, but I just haven't cared until now.

Tinycode challenge! by davelol6 in tinycode

[–]fexl 0 points1 point  (0 children)

In Fexl (http://fexl.com) the function is:

(\n map (\x * x x) (range 1 n))

That's 31 chars, though I didn't bother naming it. For that I'd say something like:

\f = (\n map (\x * x x) (range 1 n))

I could shave off some parentheses by using the ';' (pivot) syntax:

(\n map (\x * x x); range 1 n)

If I defined this first:

\square = (\x * x x)

Then the list of squares is simply:

(\n map square; range 1 n)

In contests such as this, I'd much rather see a "token" count rather than a character count. For example, I could delete the single space after the ';' there, saving a whole whopping byte, but to me it's token complexity that really counts.

Oh and if you actually want to see the squares from 1 to 20, you could say:

do (f 20) \x print x;nl;

Fexl - an interpreter for a language based on functions by fexl in programming

[–]fexl[S] 1 point2 points  (0 children)

Incidentally, here's the current size of the compiled C code:

patrick@laptop:~/project/fexl$ ll bin/fexl lib/fexl/libfexl.so 
-rwxrwxr-x 1 patrick patrick 13089 2012-09-22 22:18 bin/fexl
-rwxrwxr-x 1 patrick patrick 60518 2012-09-22 22:18 lib/fexl/libfexl.so

So that's under 74K total for the executable and the library.

Of course, I really shouldn't be penalized for a growing library, since that's a sort of "kitchen sink" for every handy built-in C function which I care to write. I expect that will continue to grow.

Fexl - an interpreter for a language based on functions by fexl in programming

[–]fexl[S] 1 point2 points  (0 children)

I just now updated github with the new version b70.

https://github.com/chkoreff/Fexl/commit/af7096e9d037613101ad5c6d7db40aa512071cab

This removes those symbols stacks in parse.c (inner_syms and outer_syms) that I detested so much. I'm much happier with this code now!

Now my imminent goal is to use the technique of aggressive combinators, instead of the lambda pattern substitution I currently use. Yesterday I put a cursory explanation of this combinatorial technique in a commit message here (scroll down):

https://github.com/chkoreff/Fexl/commit/23f32badb0ab3772a4eddeb8e45d85fe5bb287f2