You can't do length + 1 as a single expression in any language though, in python for example len(ls) + 1 is two expressions, but I get what you mean, it is a little less terse. But those commas in prolog are super useful. And you can make your example bidirectional too:
```
:- use_module(library(clpfd)).
foo(List, X) :-
length(List, Out),
X #= Out + 1.
```
```
?- foo(X, 3).
X = [_, _] .
?- foo(X, 3), X = [a,b].
X = [a, b] .
```
-----
No standarized collection types:
I think that's a feature rather than a bug. The ability to just use infix and compound terms in a generic way without it being tied to a clause or operator is a huge feature. For example:
```
pets(dog-rex-poodle, dog-fluffy-bishon).
```
That defines the collection in a semantic or mathematical sort of way, then you can pass that into whatever data structure you want, whether it's a ordered map or a hashmap or whatever.
----
No boolean values:
That's also a feature in prolog, same as having no null. It's the same sort of motivation for Haskell's Maybe and Either types or Rust's Option and Result types, same kind of usefulness.
----
Cuts are confusing:
Conditionals don't need to use cuts, the modern prolog way of doing it is using the reif library:
sign(X, S) :-
if_(X #> 0,
S = pos,
S = nonpos).
```
---
Non-cuts are confusing:
This isn't doing what you're thinking:
```
\+ (A = B)
```
It's unifying A with B, `A = B` unifies. You want `dif(A, B)`.
----
Straying outside of default queries is confusing:
It might be tempting to use bagof, but it's not monotonic. You should try to write as much prolog code as you can in a pure, monotonic way, so your code can take advantage of prolog's unique advantages, like monotonic debugging.
Check out the SWI prolog discourse group, there's a lot of good stuff in there and everyone's very supportive to newbies. And Markus Triska's website and youtube channel Power of Prolog is a super useful resource for all this stuff, a good place to go if you want to know what sets prolog apart. A lot of prolog's usefulness doesn't show up as an embedded language either, like minikanren isn't "pretty much prolog", it lacks a lot of stuff that prolog offers. Multiparadigm programming languages are also really popular now, but a lot of what sets programming languages apart isn't what they can do, it's what they can't do, what sort of paradigm or way of thinking they force you to adopt.
Oh ok, you're referring to assignment as one expression, not the PLT definition of expression, which for that example would be like 3-6 expressions depending on whether you consider x, list, and 1 to be expressions. Yeah, a complicted formula might be more verbose in prolog because there's no return statements, it's all unification, but I think that's a feature not a bug, because it allows you to create bidirectional formulas and also naturally extends to "multiple return values" in a sense, because everything is a relation.
It's not an issue. "+" is not a function in Prolog. So, for example, X = 1 + 1 means that the term 1 + 1, or +(1,1), is bound to the variable X. It doesn' t mean that 1 + 1 is evaluated, and its result assigned to the variable X. Prolog doesn't have assignment, and all its data structures are immutable, including variables, so once a variable is bound it stays bound for the scope of the current execution branch. That's unification.
The thing to keep in mind is that Prolog borrows its syntax and semantics from (a fragment of) First Order Logic, and that's where its treatment of functions comes from. In FOL there's a concept of a "term": a variable is a term, a constant is a term, and a function symbol followed by one or more comma-separated terms in parentheses is a term. So if f is a function symbol, f(X,a(b), c) is a term, where X is a variable (in Prolog notation where variables start with capital letters or _). Terms are mapped to functions over objects in the domain of discourse by a pre-interpretation (long story). Terms are arguments to atomic formulae which look exactly like terms with one or more arguments, except they have predicate symbols rather than function symbols, so if p is a predicate symbol, then p(f(X,a(b), c), d, 1, 2, 3) is an atomic formula, or atom.
There's a bit of terminological confusion here because Prolog calls everything a "term", including atomic formulae, and it calls its constants "atoms", but, well, you learn to deal with it.
The difference between terms (in both Prolog and FOL) and functions (in most programming languages) is that terms are not evaluated and they are not replaced by their values. Rather, during execution of a Prolog program, variables in a term are bound to values, by unification, and when execution is over, if you've got all your ducks in a row, all variables in your program should be bound to some term with no variables, and all terms be "ground" (i.e. have no variables).
That's because a ground term is essentially a proposition, and so it has a truth value of true or false. The point of FOL and of Prolog, and every other logic programming language is to carry out a proof of a theorem, expressed as a logic program. If a term has variables we can't know its truth value because it may correspond to a different value of a function, depending on the values of its variables. So to know the truth or falsehood of a term we need to ground it. Unification in Prolog is a dirty hack that allows the proof to proceed without fully grounding terms, until the truth of an entire theorem is known, at which point everything becomes ground (or should be ... more or less, it depends).
ASP (Answer Set Programming) instead starts by grounding every term. Then, it basically treats a logic program as a SAT formula and uses a SAT-solver to find its truth or falsehood (it does more than that: it gives you all models of the theorem, i.e. every set of ground atoms that makes it true).
And that's where the tiger got its stripes. Don't expect Prolog (or ASP for that matter) to work like other languages, it has its own semantics. You don't have to like them, but there's a reason why everything is the way it is.
I'm not sure how you would handle your specific situation, but my general take on interviews is that the interviewer isn't just screening you, in the sense that they want to know what you did and your skillset and skill level, they're also trying to figure out how well you can navigate interpersonal politics. And the problem is that for a lot of people those two things seem contradictory, because with interpersonal politics we'll intentionally spin things just slightly, not like a politician but just to maintain a good vibe and keep everyone comfortable and engaged. Like imagine if you were in a social gathering, and there's also a girl you like in there that you're trying to impress, and someone asked you about that previous role, you wouldn't drift off into a rant or anything negative because you don't want to kill the vibes of the meeting, you want to look your best because there's a girl you like there, so maybe you'd say something like "ah, it just wasn't a good fit". And if that came up while you were dating that girl you like, and she wanted to dig deeper on it, you wouldn't just repeat the same thing, because it would look like you're being evasive and she would then be on the defensive because she would've felt like she's prying too much, and it would kill the vibe, you'd just say something a little bit more, also keeping it short, and maybe mention something good about working there that you learned, and then not forcefully but try to make some room to move to another subject, or if you can do it slickly without making it feel awkward then you just shift to some other topic that feels engaging without making it look evasive. Again, it's all about maintaining a good vibe. And companies want to know the ins and outs about you, but they also just want to know that you have some social skills in doing stuff like that, because they're running a company with different kinds of people, sometimes from very different backgrounds, and they need the team to work together and feel cohesive. The company and the management are already trying to keep the company afloat and profitable, it's own engineering problem, on top of marketing, on top of operational concerns, they don't want to have concerns around political drama in the office, they want to know that you can be cool. Unless you're a boy genius from Southie, then maybe they'll tolerate a lot of weird shit from you, but you aren't a boy genius from Southie.
There does seem to be a sort of sampling bias thing that I've only recently noticed, that I think does come from being older now. I started to get back into old retro games I used to play, and I can't help but realize how many games back then were really bad, like not worth playing at all, and I just cherry picked the good ones. And being older, I'm not into gaming anymore, or really much of a consumer at all besides essential goods, being younger you do consume more entertainment products, like games. So I think there's definitely some sampling bias going on here where things look like they're getting worse. Or it could be both things, like it could actually be getting worse, but also not as much as it looks like because of this sort of sampling bias thing. Like having to have multiple accounts, like a Switch account plus some special Switch account and/or another account to play a game, or you buy a game and then there's an online store as well, or you buy a game in person but you can't get a copy digitally, or you buy a digital copy and you can't get a physical copy made for you for a flat fee, or that increasingly people don't actually literally own things anymore and it's all subscriptions or some sort of permission to use, or that a lot of games are just remakes of older games, or that you can't play single player offline, or that you can't transfer or give your digital game that you "bought" and "own" to someone else (less it be a physical copy, obviously), etc.
I mean, I see no issue with comparing high profile old games with high profile new games. The thing is thst there's less high profile bad games becsuse... Well, back then when you put in that money you werre trying to go for quality, I suppose.
It also was because development budgets were microscopic compared to today, so a bad release from a dev team of 5 people and 12 months won't bomb as badly as a 500 person 5 year "blockbuster" release. So yeah, Superman 64 was laughably bad but didn't sink a company the way Condord or even a not-that-bad game like Saints Row would.
Economy is different, as is the environment. There's still quality, but when a game flops, it's a tsunami level flop and not just a painful belly flop.
I don't know, the problem with that mentality is that you can't just separate the art from the artist, right? unless we're talking about historical figures, on some level it's validating and enabling those people and their ideology, even if you explicitly disagree with it.
I'm pretty bummed out to hear about all of this. I thought the suckless style software was pretty cool, easy to grok, minimalist. I use a lot of it. Granted, I've been planning on translating all of the minimalist C software I've been using to R7RS scheme, so maybe this just gives me more motivation to get started on porting my stack to that.
Someone in an earlier thread said something like, if he avoided software written by assholes then he would have a hard time using his computer, something like that. I think that's kind of true, but there are definitely red lines when it comes to violent ideologies.
Idk, popular people and probably influencer types look cool with a phone. They look like a VIP, people are constantly texting them, it looks like they're constantly socializing, networking, etc. Same with social media, they have like 5 million friends and it looks like a lot's going on in their lives.
That's probably the difference between how cool people use technology vs nerds or dorks. When I use my phone, it's either to look something up, study or learn something new, read the news, or talk to my mom. I would imagine I probably don't look cool using my phone.
Joking aside, I think one thing that I really don't like about smartphones and texting entering our lives is that when you're out for food or coffee people get on their phones, and it feels antisocial, like you can't talk to them now without interrupting them from whatever they're doing on their phone. In the past, I remember, if people had nothing to say, they would just sit there and look off into the distance. It all felt way more social back then, when people got together they interacted more.
;; NOTE: I won't encourage using Racket but if you really want,
;; I still give you some hints in this tutorial. But the
;; tutorial will base on Guile and RnRs.
Not sure. I could imagine it being because it is no longer a Scheme, or the creators and maintainers do no longer want it to be seen as a Scheme. Or perhaps because it introduces differences not adhering to the Scheme standards and therefore Schemers do not like it.
I liked Racket. I only found it difficult to use multiple cores dynamically with it and its places concept and lifting and multiple Racket VMs and all that. Guile seems easier in that regard. But Racket has typed racket and more advanced macro system ...
Intentionally leaving out important or key information is still lying and deception, and is harmful, and can be really harmful if it's a big thing, even in cases when it's done with good intentions.
Nobody is going to fix the problem without fixing the culture, which isn't easy to do.
The issue isn't around tasks that are predictable in nature and therefore easy to estimate with a small margin of error, it's around complexity in software, unforeseen things, bugs, etc, which can compound for larger long term projects.
If engineers give estimates close to what it would be if everything goes right, then they risk overpromising and underdelivering if something goes wrong (hofstader's law). They might've just wanted to do the right thing by saving the company money and time, but in the end they footgunned themselves.
Or engineers intentionally over-estimate in order to manage the complexity, but then you end up with a lot of padding and parkinson's law. Because as soon as the engineer starts underpromising and overdelivering consistently, management will pressure them to lower their estimates because they have a track record of doing that, so instead they're incentivized to pad and then fill up the entire time they estimated even if it took less time.
Sprints were probably invented in order to deal with some of these issues, so that people just work with a bunch of smaller tickets that are much easier to estimate, with the more complex long term estimates going to management, which are incentivized to get it right because they're shareholders. That often leads to micromanagement and burnout, and it doesn't fix the padding/overestimation issue either, it might even amplify it in a lot of cases.
People here mention giving ranges or probability distributions, and have also equally mentioned that they don't work because management wants a single number, or management just assumes the best-case or middle-case of the range as the actual estimate, and then they still get in trouble for giving ranges and it didn't solve anything. It also doesn't solve the problem of unanticipated setbacks, the whole you don't know what you don't know thing, which can only really be solved culturally in some way.
While there are certainly bad managers that want to squeeze their workers, a lot of the time management is probably also pressured to give estimates and that's why they want and need that accuracy, because they're pressured by investors and clients that want to know how much time and money something will cost.
Overall the entire problem is a system cultural issue around managing complexity.
I could see that working well for managers, if they incentivize estimates as biweekly or monthly bonuses going to the most accurate one, and each person gives a detailed estimate of ballpark plus probability of what sorts of things can go wrong and how that impacts the estimate.
The arrow and page up/down keys don't work in any predictable pattern for me, it's really weird. Like I thought it only scrolled up and down with the arrow keys if I press it 4 times, but then page up/down keys don't work no matter how many times I press it, then I focus on the page and it works, but then the arrow keys take 6 times to press before moving, and then I tried the same pattern again, and the arrow keys now take 11 presses before they start moving. Usually a lot of modern apps predictably break the back/forward history buttons and tab focus, but I've never seen anything quite like this. I guess it must be still delivering value though even if the product isn't polished.
You can't do length + 1 as a single expression in any language though, in python for example len(ls) + 1 is two expressions, but I get what you mean, it is a little less terse. But those commas in prolog are super useful. And you can make your example bidirectional too:
``` :- use_module(library(clpfd)).
foo(List, X) :- length(List, Out), X #= Out + 1. ```
``` ?- foo(X, 3). X = [_, _] .
?- foo(X, 3), X = [a,b]. X = [a, b] . ```
-----
No standarized collection types:
I think that's a feature rather than a bug. The ability to just use infix and compound terms in a generic way without it being tied to a clause or operator is a huge feature. For example:
``` pets(dog-rex-poodle, dog-fluffy-bishon). ```
That defines the collection in a semantic or mathematical sort of way, then you can pass that into whatever data structure you want, whether it's a ordered map or a hashmap or whatever.
----
No boolean values:
That's also a feature in prolog, same as having no null. It's the same sort of motivation for Haskell's Maybe and Either types or Rust's Option and Result types, same kind of usefulness.
----
Cuts are confusing:
Conditionals don't need to use cuts, the modern prolog way of doing it is using the reif library:
``` :- use_module(library(reif)).
if_(Cond, Then, Else) ```
For example:
``` :- use_module(library(clpfd)). :- use_module(library(reif)).
sign(X, S) :- if_(X #> 0, S = pos, S = nonpos). ```
---
Non-cuts are confusing:
This isn't doing what you're thinking:
``` \+ (A = B) ```
It's unifying A with B, `A = B` unifies. You want `dif(A, B)`.
----
Straying outside of default queries is confusing:
It might be tempting to use bagof, but it's not monotonic. You should try to write as much prolog code as you can in a pure, monotonic way, so your code can take advantage of prolog's unique advantages, like monotonic debugging.
Check out the SWI prolog discourse group, there's a lot of good stuff in there and everyone's very supportive to newbies. And Markus Triska's website and youtube channel Power of Prolog is a super useful resource for all this stuff, a good place to go if you want to know what sets prolog apart. A lot of prolog's usefulness doesn't show up as an embedded language either, like minikanren isn't "pretty much prolog", it lacks a lot of stuff that prolog offers. Multiparadigm programming languages are also really popular now, but a lot of what sets programming languages apart isn't what they can do, it's what they can't do, what sort of paradigm or way of thinking they force you to adopt.
reply