programming-beginners

2018-03-08T14:41:46.000016Z

I managed to solve a puzzle I couldn’t figure out for days! Feels pretty great. Now I’ve made the puzzle more complicated, but I’m not sure how to search for what I need. I can’t figure out how to identify whether or not a specific string is present in a vector of strings. Can anyone give me a hint on what kinds of functions I should be looking at, or the right keywords or phrases I should use to search for this myself?

bronsa 2018-03-08T14:43:38.000291Z

check some

bronsa 2018-03-08T14:44:16.000111Z

(string? "foo") ;=> true
(some string? [1 2 3 "foo" 4 5]) ;=> true

2018-03-08T14:46:03.000774Z

Thank you! Let me play around with that, see if I can make it work

orestis 2018-03-08T14:49:49.000378Z

Does it need to be a vector of strings? Could it be a set instead?

orestis 2018-03-08T14:51:09.000128Z

@bronsa’s answer is more about finding out the string inside a vector of random stuff, whereas @amelia wants to find "x" in ["z" "y" "x"]

bronsa 2018-03-08T14:51:36.000763Z

>how to identify whether or not a specific string is present in a vector of strings

bronsa 2018-03-08T14:51:39.000110Z

that’s not what she said

bronsa 2018-03-08T14:52:39.000567Z

some with the correct predicate will do exactly what she asked

bronsa 2018-03-08T14:52:49.000720Z

I’m not providing the right predicate of course

orestis 2018-03-08T14:53:17.000391Z

@bronsa Ah, gotcha 🙂 I got confused by the example…

2018-03-08T14:53:26.000214Z

When would you use a set instead of a vector?

orestis 2018-03-08T14:54:05.000500Z

Because sets are a datastructure that makes it quite easy to answer “is x in #{x y z}“, by their design.

bronsa 2018-03-08T14:54:25.000700Z

sets are unordered and don’t allow duplicates, they can answer the question “is X in Y” in constant time

2018-03-08T14:54:34.000324Z

What is constant time?

bronsa 2018-03-08T14:55:07.000539Z

it means that no matter how large the set is, the question will be answered in the same amount of time (roughyly)

bronsa 2018-03-08T14:55:22.000786Z

as opposed to e.g. linear where the time it takes to answer the question depends on how large Y is

orestis 2018-03-08T14:55:46.000635Z

Vectors, by design, are “linear” in this aspect — if you have 10 million elements, you have to go one-by-one and check “is this what I want”?

orestis 2018-03-08T14:56:17.000532Z

(Which is what @bronsa’s example will do, behind the scenes)

bronsa 2018-03-08T14:56:24.000435Z

generally you want to use vectors when you want to have a collection that maintains order and when you care about accessing random elements of that collection (e.g. what is the 3rd element of X), sets are used when you don’t care about order and you only care about membership (is X in Y)

orestis 2018-03-08T14:57:26.000368Z

BTW this is not Clojure specific at all — if you are interested in more detail there’s ton of resources out there about algorithms and data structures, the basic building blocks of all programs.

2018-03-08T14:57:41.000836Z

That’s really helpful, thank you! I should definitely use a set, I don’t care about order in this case.

bronsa 2018-03-08T14:58:04.000114Z

in that case you probably want contains? with a set

bronsa 2018-03-08T14:58:18.000622Z

(contains? #{"foo" "bar"} "foo") ;=> true

orestis 2018-03-08T14:58:44.000343Z

Sets are also special in clojure in that you can treat them as functions:

user=> (#{1 2 3} 2)
2
user=> (#{1 2 3} 4)
nil

orestis 2018-03-08T14:59:35.000802Z

Beware that contains? will not work with vectors the way you’d expect:

orestis 2018-03-08T15:00:09.000806Z

user=> (contains? ["a" "b" "c"] "b")
false
user=> (contains? ["a" "b" "c"] 2)
true

2018-03-08T15:00:20.000306Z

Ah…

2018-03-08T15:00:26.000782Z

That makes sense. Thank you!

orestis 2018-03-08T15:00:41.000019Z

user=> (doc contains?)
-------------------------
clojure.core/contains?
([coll key])
  Returns true if key is present in the given collection, otherwise
  returns false.  Note that for numerically indexed collections like
  vectors and Java arrays, this tests if the numeric key is within the
  range of indexes. 'contains?' operates constant or logarithmic time;
  it will not perform a linear search for a value.  See also 'some'.

orestis 2018-03-08T15:01:25.000822Z

I got bit by this when I started doing Clojure — most other languages will give you something like contains? for vectors/arrays, but Clojure will by design not, because you might accidentally slow down your program.

2018-03-08T15:14:49.000483Z

That’s really interesting. I do wonder if I’m having a better experience in some ways of coming to Clojure as a complete newbie than programmers who have other languages to shape their thinking. It’s taking some time to adjust to the mathematical expressions, but once I accept the new meaning of a word like ‘argument’ or ‘reduce’ that’s all there is. No competing definitions or expectations.

orestis 2018-03-08T15:25:46.000453Z

Yup — I’d love to read a writeup of your experiences so far. I wouldn’t suggest Clojure as a good “first language”, but perhaps the gotchas I have in mind are just irrelevant if you don’t come from a different language background.

bronsa 2018-03-08T15:26:25.000652Z

yeah I don’t know if I’d say clojure is a good first language — it’s definitely focused on experienced users and professionals

2018-03-08T15:26:54.000494Z

When you say ‘it’ do you mean the language itself or the support infrastructure though?

2018-03-08T15:27:09.000618Z

I’ve found that to be extremely true for the latter - not so much for the former.

bronsa 2018-03-08T15:27:20.000027Z

both

bronsa 2018-03-08T15:27:29.000252Z

there’s languages that are significantly more beginner friendly

2018-03-08T15:27:36.000698Z

Such as?

bronsa 2018-03-08T15:27:39.000836Z

in both tooling/infrastructure, guides and the language itself

bronsa 2018-03-08T15:27:45.000354Z

racket for example if you want to stick to lisps

2
bronsa 2018-03-08T15:27:54.000184Z

it’s great and intended for teaching

orestis 2018-03-08T15:28:31.000636Z

Actually I think that the Lisp-nature itself is quite simpler to get started with syntax. Python for example has a more “traditional” syntax that takes some time to grok if you’ve never programmed before.

orestis 2018-03-08T15:28:56.000200Z

I’m curious to know how did you approach Clojure — read a book, online guide?

2018-03-08T15:29:05.000938Z

Over the past year I’ve been to a number of introductory workshops and started studying a number of languages, including Ruby, Python and Javascript. I’ve never got very far with any of them.

2018-03-08T15:29:32.000586Z

I attended a ClojureBridge workshop here in London, liked it well enough, and was impressed by how inclusive and supportive the community seemed.

2018-03-08T15:29:58.000683Z

I attended a second workshop last Saturday, and, in reviewing the same workshop materials, things I remembered struggling over last time I breezed through this time.

bronsa 2018-03-08T15:30:27.000146Z

by all means I’m not saying don’t use clojure as a first language btw

2018-03-08T15:30:30.000020Z

I’ve never experienced that with a language before.

bronsa 2018-03-08T15:30:37.000154Z

I’m just saying it’s not the easiest first language one could pick

bronsa 2018-03-08T15:30:55.000040Z

it’s definitely a great first language to learn, just not an easy first language

orestis 2018-03-08T15:31:13.000192Z

Ooh, do you remember which things you were struggling with?

2018-03-08T15:31:29.000892Z

Well, it’s not like I selected it and threw all my effort into it because I decided it would be the best starting point or anything. I tried a bunch of things, and Clojure was what stuck first.

2018-03-08T15:32:11.000289Z

One sec, I’ll check exactly what I struggled with before that was easy now…

2018-03-08T15:33:11.000938Z

It was collections. Drawing up vectors of maps then changing them by using conj etc.

joelsanchez 2018-03-08T15:33:27.000364Z

this conversation reminds me of when I began programming, it was php...I was very confused by the fact that . was the string concatenation operator (`str` is much more intuitive, isn't it...)

2018-03-08T15:33:50.000133Z

I’ve been wondering where all those full stops have come from! I’ve seen them around.

2018-03-08T15:34:07.000103Z

The fewer bits of punctuation lying around, the easier it is for me to read.

2018-03-08T15:34:15.000041Z

Another reason I like Clojure 🙂

bronsa 2018-03-08T15:34:18.000631Z

the easier it also is to google for stuff :)

2018-03-08T15:34:25.000455Z

Yes, exactly!

orestis 2018-03-08T15:34:31.000515Z

How about immutable data structures?

joelsanchez 2018-03-08T15:34:45.000559Z

there's this article which did wonders for me, begginning with clj https://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful-characters-of-clojure/

2018-03-08T15:35:15.000819Z

Immutable data structures aren’t a problem, because I’ve never known any differently. In fact, it seems to limit the number of errors I can make.

orestis 2018-03-08T15:35:46.000410Z

When I was doing my master’s thesis, I was learning Python — and because I sorted a list in-place, my program was producing garbage. That took me 2 months to figure out, and I thought I’m an idiot and I’ll never be a programmer.

orestis 2018-03-08T15:36:17.000100Z

(I was offline for those two months, staring at the code, not figuring out what was going on)

2018-03-08T15:37:14.000787Z

That’s how I’ve always felt with other languages. And I’ve given up and walked away.

orestis 2018-03-08T15:38:12.000406Z

Mind you, I was already working professionally for a few years before that, in Java. I cannot imagine what would it be if I was trying things for the first time.

2018-03-08T15:38:47.000411Z

I honestly don’t know what the reason is, but something has really stuck this time. Every day since the workshop I’ve been logging on to try and fix a bit more of whatever puzzle I’ve been working on.

2018-03-08T15:39:06.000131Z

It’s just fun. I like puzzles, and the barrier to entry feels reasonably challenging but not insurmountable.

2018-03-08T15:39:22.000536Z

I’ve solved two puzzles on my own since the workshop on Saturday. It’s felt amazing.

orestis 2018-03-08T15:39:43.000078Z

What puzzles are you doing? I learned Clojure via adventofcode, but some might be a bit too hard.

2018-03-08T15:40:03.000598Z

Just continuing work on the ClojureBridge materials, though interpreting it to suit myself!

orestis 2018-03-08T15:40:18.000486Z

(And I got the same impression of the community — I’ve stuck around mostly because of how welcoming is everyone)

2018-03-08T15:40:33.000499Z

One of the exercises is ‘make a sandwich’. They have a specific way of solving it, but I didn’t like that way so I changed the question.

2018-03-08T15:41:23.000253Z

I decided I wanted to be able to create a list of ingredients ("bread" "cheese" "tomato") and add “sliced ” to the front of each of them so the list would become ("sliced bread" "sliced cheese" "sliced tomato")

2018-03-08T15:41:31.000354Z

I’m sure it sounds really simple, but it took me DAYS

2018-03-08T15:41:47.000075Z

I roped in the iOS developers and platform engineers I work with, none of whom know Clojure

2018-03-08T15:42:00.000590Z

Just hearing and seeing how they approached it as a programming problem regardless of language was really interesting!

2018-03-08T15:42:29.000246Z

But eventually I solved it on my own:

2018-03-08T15:42:39.000150Z

(def ingredients ["bread" "cheese" "tomato" "lettuce"])

(defn slice [ingredients] (str "sliced " ingredients))

(map slice ingredients)

2
2018-03-08T15:43:17.000530Z

Basic, right? 😂 But I had fun figuring that out. It didn’t get frustrating, I just had to go through the Clojure docs, pay attention, try new things, watch it break, try more things, go through the docs again, try more things, and so on.

2018-03-08T15:43:33.000312Z

It hasn’t been frustrating at all, even when I’ve hit brick walls.

2018-03-08T15:44:12.000416Z

I’ve got so, so frustrated with the other languages I’ve tried, and very early on, too - exactly when I would expect things to be easiest and most enjoyable.

2018-03-08T15:44:43.000132Z

So now I’m trying to butter just the bread in that sandwich! Don’t give me the answer though, I want to work it out for myself. 🙂

orestis 2018-03-08T15:45:13.000481Z

Tiny nitpick — you’re reusing ingredients in both the def and as an argument to slice. It hurts readability a bit, though it’s technically not an issue. I’d rename the ingredients in slice to ingredient, or, in Clojure tradition, just x 🙂

2018-03-08T15:45:26.000122Z

Thank you!

orestis 2018-03-08T15:46:03.000506Z

I’m loving this conversation. Do you mind if I copy some of your quotes for a future blog post? Anonymous or Eponymous, whatever your prefer.

2018-03-08T15:46:15.000510Z

No, that’s totally fine, and you can use my name

2018-03-08T15:46:32.000358Z

I’ve been thinking of writing a blog post myself - I’m leaving my job soon and will be putting more time into this

2018-03-08T15:46:46.000560Z

So when using defn I should always just use x for the argument?

orestis 2018-03-08T15:47:09.000805Z

I think that functional programming with immutable data is much closer to math and can be reasoned about, whereas “mainstream” programs can be much more complex.

2018-03-08T15:47:10.000431Z

I’ve been struggling a bit with functions in general, so good to understand the basics a bit better in any way I can.

2018-03-08T15:47:42.000828Z

The maths part is what’s been hardest, in some ways - I never liked it, and haven’t studied it since I was 16.

orestis 2018-03-08T15:47:57.000272Z

Well, x it’s “just” a name — you can name it whatever you want. It is valid only inside the functions (technically, its scope is the function body).

2018-03-08T15:47:59.000749Z

I’m not really used to logical thinking like this. I was a ‘creative’ kid, and my degree is in Japanese.

orestis 2018-03-08T15:48:19.000297Z

“Just” is in quotes because there’s a running joke that naming things is one of the hardest things in computer science.

2018-03-08T15:48:20.000573Z

Although I have noticed some parallels between Japanese and Clojure that have been pretty interesting… That I may write about at some point.

2018-03-08T15:48:54.000324Z

So I should name it something then? Or I shouldn’t? What’s the convention?

sundarj 2018-03-08T15:49:17.000739Z

the convention is to use x when it doesn't matter what the parameter is called

orestis 2018-03-08T15:49:19.000014Z

Clojure has a tradition of using very short names in simple functions like this. You may have seen this in the docstrings of the core functions.

orestis 2018-03-08T15:50:40.000010Z

Just to clarify, the suggestion is:

(defn slice [x]
  (str "sliced " x))

2018-03-08T15:50:53.000802Z

Thank y ou!

2018-03-08T15:50:57.000090Z

That’s really helpful.

orestis 2018-03-08T15:51:28.000651Z

But this is equally valid:

(defn slice [ingr]
  (str "sliced " ingr))

orestis 2018-03-08T15:51:49.000251Z

Sometimes you might want to give a more meaningful name when you are solving a puzzle.

orestis 2018-03-08T15:52:00.000183Z

This is just helping you read the program, the compiler doesn’t care.

sundarj 2018-03-08T15:52:12.000061Z

and if you want to be able to skip naming something entirely, you can use partial instead: (def slice (partial str "sliced "))

orestis 2018-03-08T15:52:14.000446Z

My initial comment was only that you had a variable ingredients, and reusing the name also an argument in a function is risky (though also technically correct) — a typo might lead to a 2 hour pull-your-hair debugging session 🙂

bronsa 2018-03-08T15:52:18.000622Z

there’s definitely many parallels between learning a new programming language and learning a new natural language

2018-03-08T15:53:27.000603Z

It’s interesting that you say it hurts readability - from my perspective right now, the more words get replaced by non-words, the extra burden I have to guess/remember when reading. So that suggests that professional Clojure code will be harder for me to read, because of the preference for shorter names or no name at all.

2018-03-08T15:53:53.000741Z

But with Japanese specifically, though.

sundarj 2018-03-08T15:54:08.000075Z

use a name when it helps readability, use a generic name like x when it doesn't 🙂

2018-03-08T15:54:29.000748Z

For example, there are particles in Japanese that almost directly map onto def and let. I understood the concept of global and local scope immediately because of it.

bronsa 2018-03-08T15:54:29.000897Z

interesting :) I don’t know japanese so I couldn’t tell

bronsa 2018-03-08T15:54:42.000462Z

that’s super interesting

bronsa 2018-03-08T15:54:45.000901Z

I would read a blog post about it

2018-03-08T15:55:11.000547Z

You’re not the first to say that! Once I’m out of work I think I’d like to write one.

sundarj 2018-03-08T15:55:13.000479Z

for example, the parameter for inc i s named x, because naming it number wouldn't really help much

2018-03-08T15:55:43.000377Z

Why wouldn’t it?

orestis 2018-03-08T15:57:18.000401Z

I have to side with Amelia on this one — the single letter parameters can be a bit too much some time, esp. if you are in unfamiliar territory.

bronsa 2018-03-08T15:57:25.000756Z

one thing that I’ll suggest to a complete beginner (feel free to ignore my advice if you think trying to learn too many things at once would be too much) — would be to not focus so much on learning a new language as much as learning the algorithmic way of thinking. this is one of my biggest issues with e.g. clojurebridge or http://code.org where they give the language a bit too much focus IMO studying something like https://mitpress.mit.edu/sites/default/files/6515.pdf would be what I’d suggest a beginner do first — and then learn a particular language

sundarj 2018-03-08T15:57:59.000131Z

well, at least to me - number doesn't add any value over x, since inc already means 'increment a number`

2018-03-08T15:58:14.000154Z

I take your point, but it does raise the barrier to entry.

sundarj 2018-03-08T15:58:18.000686Z

so there's no need to specify

2018-03-08T15:58:22.000910Z

Right now I’m having fun solving puzzles

2018-03-08T15:58:42.000354Z

Once I get to a point where I feel like I’d like to continue solving puzzles and be able to solve more complicated puzzles, that seems like the right time to seek out more knowledge

sundarj 2018-03-08T15:58:43.000713Z

i think it's better to name things only when that name adds value

2018-03-08T15:59:19.000168Z

I do know what you’re saying, not least because I saw this in Japanese too - people jumping in and learning through experience struggled to get to my level of fluency without the benefit of a rigorous education in grammar.

sundarj 2018-03-08T15:59:22.000013Z

but of course, this is a matter of taste :~)

bronsa 2018-03-08T15:59:33.000718Z

yep that’s completely understandable — it’s just that I’ve seen way too many people going down that route and hitting a point where the lack of training in “algorithmic/abstract thinking” makes them hit a brick wall

2018-03-08T15:59:40.000798Z

I can see that, for sure

bronsa 2018-03-08T15:59:54.000220Z

so keep this in mind when you’ve advanced a bit

orestis 2018-03-08T16:00:25.000375Z

@sundarj of course, the docstring for inc refers to “num” while the parameter is named x:

clojure.core/inc
([x])
  Returns a number one greater than num. Does not auto-promote
  longs, will throw on overflow. See also: inc'

2018-03-08T16:00:35.000653Z

As things stand, I’m approaching coding very similarly to the way I approached Japanese. I probably spent about a year learning the pretty alphabets and writing out song lyrics just for fun, then when I realised I wanted to commit to serious learning I applied for my degree.

sundarj 2018-03-08T16:00:51.000184Z

hah, guess they changed the param but forgot to change the docstring

orestis 2018-03-08T16:00:58.000768Z

Or the other way round? 🙂

2018-03-08T16:01:03.000154Z

I can’t do another degree, but I can certainly see the value both in some early experience-based learning to build up an appetite for more rigorous study of fundamentals, and the study itself.

sundarj 2018-03-08T16:01:22.000398Z

possibly 🙂

orestis 2018-03-08T16:03:14.000953Z

BTW, I’m going through the ClojureBridge curriculum — it’s very well done. @amelia do you use Nightcode?

2018-03-08T16:03:24.000494Z

I do now!

sundarj 2018-03-08T16:03:39.000150Z

i know Japanese to an intermediate level (it's my favourite natural language by far), curious which particles you're referring to

2018-03-08T16:03:40.000536Z

Though I’ve just been using the REPL on the workshop pages for the puzzles I’ve been working on

2018-03-08T16:04:47.000550Z

は (global scope) and が (local). :)

2018-03-08T16:05:28.000157Z

Not a direct relation, as the wa can be replaced by another wa at any time, but it was enough to help me grasp the concept of global vs. local.

sundarj 2018-03-08T16:06:20.000553Z

ooh, that's neat! i've never thought about them like that before 🙂

orestis 2018-03-08T16:06:33.000004Z

Good good — I might sign up for ClojureBridge to help with any upcoming event in my area 🙂

orestis 2018-03-08T16:06:47.000712Z

I need to go back to actual work now though…

sundarj 2018-03-08T16:07:08.000494Z

i do love thinking about the connections between linguistics and computer science

2018-03-08T16:09:04.000369Z

I’ve also been thinking about the concept of kanji compounds as immutable data structures, with the attached verb endings the equivalent of functions, but I’m not sure yet how precise that is!

2018-03-08T16:11:21.000473Z

Me too 😂

2018-03-08T16:11:33.000309Z

I’m a bit obsessed at the moment, I just want to spend all day playing with Clojure…

sundarj 2018-03-08T16:16:24.000355Z

interesting!

sundarj 2018-03-08T16:17:36.000592Z

did you know there's a programming language called Perl that was created by a linguist? its design is informed by linguistic principles, which i think is pretty neat

orestis 2018-03-08T16:20:02.000110Z

Been there 🙂

sundarj 2018-03-08T16:27:41.000435Z

thinking about this some more, using a function with map is like using a verb with すべて