> I am may not be familiar with the kinds of languages you speak of, where there are no variables (and no functions/procedures? No names at all?) but "still have very powerful expression-building capabilities." I'm not totally sure what you're talking about, i admit.

I venture you probably are familiar with them (even at least somewhat), but you might not think of them as languages. Or perhaps you are turned off because they are oblique.

Regular expressions are a good example, because they're really common. Here's a program I use frequently:

"([^"\\]*(\\.[^"\\]*)*)"

Incidentally, this shows off an interesting and useful power of grouping. Too many people learn grouping and capturing at the same time, and capturing seems so much more useful that the second use of parenthesis is missed.

Another good example to consider is pointfree Haskell[1]. This is typically sold to programmers as a kind of golf, but this combinational style can make it possible to spot optimisations that are difficult in a pointful implementation. If you don't like types, you also see a lot of this in languages in the Forth family: Simple "improper" functions like : K 1024 * ; are really common, with no effort at all to give names to arguments of short functions, but people sure do like their stack diagrams...

[1]: https://wiki.haskell.org/Pointfree

> It's not about the name, it's about the boundaries of the concept, but how do humans establish a concept and it's boundaries without giving it some kind of name to refer to?

Consider the following function:

def m(f,a): [f(x) for x in a]

It is very easy to come up with a name for "m" but it is difficult to come up with a useful name for "f" or "a", so we typically don't. In APL we call f ⍺⍺ or ⍵⍵, and a we call ⍺ or ⍵, and you typically do not name your arguments at all (you can, of course), but it's very liberating not having to think of names for these things! When using other languages, I will typically name function-arguments f or g, and non-functional arguments x and y, but this is just a convention I use.

Of course we would never need to write m in APL because it's just ¨

> I think taking logic and putting it in a procedure with a name is the fundamental tool of abstraction offered by such an environment.

Your brain is the fundamental tool of abstraction!

If you want to create a ledger for tracking deposits and withdrawals from an account, you may build an abstract transaction log that can contain any values - and you could just as easily be able to use it for a bank account as for a shopping cart or fuel tracking in an airplane. And yet, being "too abstract" may mean the code is too hard to use (successfully, or it's too slow, or whatever) - it might be so much easier to build something simpler and more concrete, even if it means you have to write "basically the same thing" when you decide you're done making bank accounts and it's time to start making shopping carts.

The thing to keep in mind is that it's you deciding when it's easier and when it's harder. That's why so much of programming seems subjective, and people have strangely confusing rules, because we don't all read code the same way; we don't all have the same software experiences that lead us to think a certain way.