Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I also would to call Dockerfiles imperative on syntactic grounds alone, but I feel they have decalartive semantics in a way that's noteworthy.

> But from the perspective of 'each line of code declares a new program', then we consider the code snippet a declaration of a program.

The critical difference is that each line in a Dockerfile yields (declares) a filesystem state which can be referenced and recreated. In contrast, in your example, I have no way to say "give me a snapshot of the system between the third and fourth instructions".

Dockerfiles have all sorts of rules and restrictions that make these semantics possible. You cannot create loops; there is nothing like a "function", at least within the context of one Dockerfile.

> One of the things which makes Dockerfiles imperative is the sequence of Dockerfile commands is significant; if you swap the order of a COPY, RUN to a RUN, COPY, the result changes significantly.

I reject this line of reasoning, simply because decalative languages are indeed order-dependent:

    let y = f(g(x))
is different than:

    let x = g(f(x))
Much in the same way that these are different:

    FROM x AS y
    RUN g
    RUN f
   
vs

    FROM x AS y
    RUN f
    RUN g


If you call things “declarative” or “imperative” on syntactic grounds, which would you call Ansible (like Docker, a devops tool, famously using pure YAML but in many cases for basically running a bunch of scripts)?

It’s just not a reasonable way of making the distinction; claiming X is “imperative” because you are using it in imperative ways is logically flawed, it is not a statement of truth about X.

Dockerfile is fundamentally declarative, as you note (that’s just how Docker works: every line describes a layer), and it has not even enough features to make it imperative (control flow? goto?).


I think it is fair to distinguish between syntax and semantics here.

Haskell's "do" notation is frequently described as an imperative syntax for functional/declarative transformations. I would put Dockerfiles in the same boat. They behave declaratively, but users can think imperatively when they write them (to a certain extent) and this is part of what makes them more accessible to newcomers.

Ansible is a great example of the opposite. It looks declarative but, like you said, basically runs a bunch of scripts one after another on a system, with state and all.


> I reject this line of reasoning, simply because decalative languages are indeed order-dependent

Eh, I can kinda see that. -- It's possible to imagine a declaration where the order of items in a list has consequence.

Still, I'd Dockerfiles as a sequence of statements more akin to a bash script than to an SQL expression.


This is a deeply mistaken view informed by the cargo-culting devops traditions of yore. A Dockerfile is a declaration of layers that does not resist being used in imperative way, in which sense it’s no different from YAML or any functional language you can think of.


Yeah, to pile on, I often see this line of thinking:

> Still, I'd Dockerfiles as a sequence of statements more akin to a bash script than to an SQL expression.

lead to some quite inefficient and poorly-factored Dockerfiles.




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

Search: