News for hackers. Stuff that matters.
Re:The unreasonable effectiveness of declarative programming by bollu on Tuesday May 19, 2020 @01:37AM (#23231571)
I wrote this to show off how to write a compact and powerful animation library. It turned out to be a nice case study in declarative programming as I wrote it! I'd love feedback on the API design, website design, and content as I'm trying to actively improve in all of these areas.
Re:The unreasonable effectiveness of declarative programming by YeGoblynQueenne on Tuesday May 19, 2020 @07:56AM (#23233847)
Thank you for the interesting post. Can you explain why the "A complex animation" code example is declarative?

I can see that the names of the functions are declarative in style but the code is a series of function calls that seem to be giving instructions to the javascript interpreter to perform a sequence of operations. For example, you describe the code as follows:

    1. anim_const(name, val) to set a constant value val to name name.
    2. anim_interpolated(ease, name, val, time) to change to a named value with name 
    name to value val in duration time.
    3. anim1.seq(anim2) to run anim2 once anim1 has completed.
    4. anim1.par(anim2) to run anim2 in parallel with anim1.
    5. anim_delay(time) to do nothing for time time.
All these function calls are described by verbs like "set a ... value", "change to a ... value", "run", "do" etc. The way I understand declarative programming (I do most of my coding in Prolog these days) it means that one declares what is the state of the progam, rather than describing what steps should be taken to change it. But your code seems to be describing steps to change the state of the program. It is "do this, then do that" style of coding.

Do you mean something else by "declarative"? Could you say what you mean by "declarative"?

Re:The unreasonable effectiveness of declarative programming by jerf on Tuesday May 19, 2020 @11:16AM (#23235767)
"Declarative programming" at its core seems to be about separating what the code says from what it does, and trying to put more "magic" in between the saying and the doing. But that's not a binary distinction for all kinds of reasons. What a code "says" is already a bit subjective to start with, but then we get into things like, is this "declarative"?

    def SayHello():
        print("Hello!")

    SayHello()
After all, when I type "SayHello()", I'm not specifying how I want Hello to be Said, just that I want it said. Yet, of course, if this is called "declarative" than the word is stripped of all meaning, and we do clearly want it to mean something.

Personally I'd set the line as being somewhere where by definition of the system, there is a barrier set up and you are no longer allowed to "see into" the implementation because it's going to do things so crazy to your declaration that allowing you to see into it would ruin it. e.g. in SQL when you send in your query the query engine is reserving the right to rewrite it in absolutely crazy ways, and in principle, you have no right to ask about what it actually did as long as you get the "right answer". This is because I then like to segue into how that barrier is somewhat illusory because it's always going to take some concrete actions and you may have need to see into those actions. But that isn't the only place to draw the line, it's just where I find it convenient to draw the line so I can ride a pet hobbyhorse. There isn't really a bright line, even though there is clearly some real difference we are trying to talk about.

Re:The unreasonable effectiveness of declarative programming by YeGoblynQueenne on Tuesday May 19, 2020 @01:21PM (#23237461)
My opinion is of course coloured by my experience with Prolog but the way I understand "declarative programming" describes a style of coding rather than any particular programming language features. Hiding the details of execution is not necessary and the compilers and interpreters of most languages do that anyway.

To give an example of what I mean, here's a typical C function that concatenates two linked lists [1]:

  void concatenate(struct node *a,struct node *b)
  {
      if (a->next == NULL)
          a->next = b;
      else
          concatenate(a->next,b);
  }
And here's the same thing in Prolog:

  append([],Ys,Ys).
  append([H|T],Ys,[H|Zs]):-  
    append(T,Ys,Zs).
append/3 is a Prolog predicate that can be used to concatenate two lists. It's a little difficult to get your head around it the first time you see it but basically one interpretation of it is that concatenating a list Ys and the empty list yields the list Ys; and concatenating the non-empty list [H|T] (for "Head" and "Tail") with a list Ys yields the concatenation of the tail, T, of [H|T], with Ys.

append/3 and concatenate() share the same procedural interpretation: "to concatenate two lists walk through the first list until you find the last element in its tail ("[]" in Prolog, NULL in C) and make that element be the first element of the second list [2]".

The difference is that Prolog's declarative interpretation describes not only concatenation of two lists, but also their difference. Indeed, append/3 can be called in different instantiation modes to perform both tasks:

  % Zs is the concatenation of _Xs and _Ys
  ?- _Xs = [a,b,c], _Ys = [d,e,f], append(_Xs,_Ys,Zs).
  Zs = [a, b, c, d, e, f].

  % Zs \ Xs = Ys
  ?- _Xs = [a,b,c], _Zs = [a,b,c,d,e,f], append(_Xs,Ys,_Zs).
  Ys = [d, e, f].

  % Zs \ Ys = Xs
  ?- _Ys = [d,e,f], _Zs = [a,b,c,d,e,f], append(Xs,_Ys,_Zs).
  Xs = [a, b, c] .

  % Starting a variable with an underscore, like in _Xs, _Ys, _Zs, stops the
  % Swi-Prolog runtime from printing the bindings of the variable and
  % cluttering the screen with values you already know ;)
In short, the definition of append/3 doesn't (just) tell the computer to concatenate two lists to yield a third list, like the C program does. Instead, it describes a relation between three lists that is true under certain conditions, specified by the programmer who wrote append/3. It's this property of describing the shape of data, rather than splitting your code into data and operations on data, that mark code as declarative rather than procedural [3].

________________

[1] Copied from: https://www.codesdope.com/blog/article/concatenating-two-lin...

[2] "Behind the scenes" both Prolog interpreter and C compiler have the same "view" of computer memory and the pointers from an element in a list to the next. However, the point here is not that the Prolog interpreter "hides" this fact. If you squint a bit- it doesn't. [H|T] is the concatenation of H and T and you can very well read it as a pointer from H to the first element of T.

[3] And note of course there are more purely declarative languages than Prolog, like Answer Set Programming. But, I know Prolog and You Can't Teach an Old Dog New Tricks (old dogs know all the tricks :P).

Re:The unreasonable effectiveness of declarative programming by jcelerier on Tuesday May 19, 2020 @04:37AM (#23232676)
Not that I want to disparage as the library looks neat and clear, but is that what declarative means in 2020 ? The code looks like mainly a builder pattern for an animation datastructure.

I've always heard declarative as a sort of synonym to programs defined in terms of equational reasoning such as Lustre for instance - a rule of thumb to separate declarative languages from imperative languages is that in declarative languages

    x := 1 
    y := x + 1
    x := 2
y will be 3 as "y := x + 1" must hold.

e.g. it's not enough to just construct a graph-like datastructure for things to be declarative, the language has to do it itself.

Also, note that the par / seq model (https://en.wikipedia.org/wiki/Series-parallel_graph) is not as powerful as a general dag as things such as the K4 graph cannot be represented in it - even though it may make sense in some animation scenarios.

Re:The unreasonable effectiveness of declarative programming by wereHamster on Tuesday May 19, 2020 @04:45AM (#23232727)
IMHO in a declarative language your example should be an error. You defined x twice. Intentionally or not, this is confusing, for others and for you in a week when you have to look at the code again.

Also, why should the second binding override the first? You introduced a temporal dimension where later lines of code somehow override earlier lines of code. That is not a necessity in a declarative language. It may be how we humans read text (from top to bottom), but it does not mean the computer has to process it in the same way.

Re:The unreasonable effectiveness of declarative programming by jcelerier on Tuesday May 19, 2020 @05:21AM (#23232915)
> IMHO in a declarative language your example should be an error. You defined x twice. Intentionally or not, this is confusing, for others and for you in a week when you have to look at the code again.

c'mon, this is an example in a forum post ! of course it doesn't make sense in real life. real life is

   distance := computeDistanceToCenterOfScreen(cursorPosition)
   text := "the current distance is: " + distance
but that just muddies the waters needlessly

> Also, why should the second binding override the first? You introduced a temporal dimension where later lines of code somehow override earlier lines of code.

yes, some languages work like that, but it's not the point - either you assume that you can update values in your declarative bindings like that, or you have to define your binding in terms of some external behaviour that will change in magic ways, which again would not be very nice to do as a simple forum post example

Re:The unreasonable effectiveness of declarative programming by YeGoblynQueenne on Tuesday May 19, 2020 @08:01AM (#23233879)
>> IMHO in a declarative language your example should be an error. You defined x twice.

This would be an error in a language with immutable data structures. Declarative and immutable are not the same thing and there is nothing that says a declarative language must have immutable data structures.

Re:The unreasonable effectiveness of declarative programming by sp332 on Tuesday May 19, 2020 @09:39AM (#23234747)
I think the idea is that declarative statements use "equals" like math uses equals, not as assignment. If you say x = 1 and then later say x = 2, that is a contradiction. Usually if you evaluate each statement in order from top to bottom, that is procedural programming. And if you don't do that, it's hard to assign multiple values to one variable because you need a way for the compiler to know when the variable has each value.
Re:The unreasonable effectiveness of declarative programming by the_af on Tuesday May 19, 2020 @01:40PM (#23237729)
> This would be an error in a language with immutable data structures

It's an error from the point of view of equational thinking; (im)mutabilty is not involved.

The name `x` cannot be 1 and 3 simultaneously. It's either 1 or 3. So in the allegedly declarative program, the programmer first claimed name `x` is bound to the value 1, but later claimed it's 3. That's the error.

This has nothing to do with mutating data structures. Like the sibling comment notes, there is not "first-this-then-that" order of evaluation, so you cannot read this as "first `x` means 1, but later it means 3", because there are no notions of "first" and "later".

Re:The unreasonable effectiveness of declarative programming by Aqueous on Tuesday May 19, 2020 @06:50AM (#23233443)
there’s a lot of different perspectives on what declarative actually means but in my view it means creating a description of what you want rather than how you want it done. in that sense I think the article qualifies. what you have above is also declarative in the sense that you are describing rules, not how to solve for them. i believe this is kind of declarative is ‘constraint programming’ and also qualifies.
Re:The unreasonable effectiveness of declarative programming by naringas on Tuesday May 19, 2020 @10:59AM (#23235565)
I agree, my go-to example of declarative programming is SQL

you say what you want, and the DB figures out how best to get it.

Re:The unreasonable effectiveness of declarative programming by dmix on Tuesday May 19, 2020 @03:49AM (#23232368)
These are the type of blog posts I miss on HN. It used to be what was all over the homepage. Thanks for taking the time to write it.

One bit of feedback: the sliders are almost impossible to click on with a mobile browser. The drag handle should be much larger. There’s also a horizontal scroll bar that appears partially above the bottom of the page, something is overlapping the main content body.

Re:The unreasonable effectiveness of declarative programming by amatic on Tuesday May 19, 2020 @07:36AM (#23233707)
Which mobile browser? Android Chrome looks nice, draggable sliders, all animations working.
Re:The unreasonable effectiveness of declarative programming by r_deckard on Tuesday May 19, 2020 @09:17AM (#23234528)
I can’t seem to drag it on iOS safari.
Re:The unreasonable effectiveness of declarative programming by RangerScience on Tuesday May 19, 2020 @04:29AM (#23232624)
Very cool. I overall very much like both your library, and your presentation.

That said, I found the abbreviations initially confusing. For variable names and symbol/strings, maybe hold off until not the first example? For the functions themselves, can you do a non-abbreviated alias?

I also missed the `par` in `seq((...).par(...))` the first time. And, personally, I think `par([...,...])` would be clearer, and allow for some beneficial constructs - is there a way to allow both?

Particularly, I really admire the time travel aspects; that you can, what that means, and what allows that to happen.

It reminds me a lot of what I've tried to do (not as elegantly, so I might come crib from you!) with the pattern renderer in https://github.com/rangerscience/butterfly

Re:The unreasonable effectiveness of declarative programming by effie on Tuesday May 19, 2020 @08:22AM (#23234031)
> website design

I like the font used for the code, very readable. But underscoring keywords is superfluous and makes the code listing weird - bold font is enough. Also, the line numbers are jarring, they are too pronounced and they are not important to the reader. Maybe make them gray or put them on the right-hand side. This is a common problem with many blogs. I don't care about the line numbers!

The main text is hard to read - this font, a kind of an hybrid of serifs and tall quasi-monospace characters, is weird and hard to read. Try more usual sans-serif font with shorter-height characters, I think it will be much better both for readability and more distinct from the code listings.

The paragraph symbol is obsolete, I would lose that. At least don't make it look like a link, nothing happens when I click it.

Re:The unreasonable effectiveness of declarative programming by carapace on Tuesday May 19, 2020 @12:18PM (#23236616)
I really like your website design, very clean and readable without sacrificing style.

The library is very nice too. The only thing I would add is, uh, rub some Category Theory on it. It seems like you could "go all the way" and define a formal mathematical semantics for animations, which would be nice. VPRI STEPS project made a quasi-mathematical language called Nile for compositing 2D vector graphics ( http://www.vpri.org/pdf/tr2009016_steps09.pdf ) that might be something to look at.

Re:The unreasonable effectiveness of declarative programming by agys on Tuesday May 19, 2020 @09:00AM (#23234357)
Small typo:

  On being invoked, it sets out.v = field 
should be:

  (…) out.field = v
Re:The unreasonable effectiveness of declarative programming by imglorp on Tuesday May 19, 2020 @08:15AM (#23233974)
I appreciate the simplicity and visual style of the blog.