Anyone got any ideas on what's the quickest way (execution speed) to verify that a variable contains JSON?
Right now I'm just doing a simplistic check to make sure it starts with "{" or "[". If something fails after that, then I deal with it there. But it would be nice if I could do better than that, without costing me much time.
It's not a huge issue or anything, but I thought I'd see if anyone had any ideas.
I mean, I could dop into JXA to test it, but that's not very fast, execution-wise.
I am not good in writing Regular Expressions but I would definitely recommend going this route and check for all possible patterns youād like to test.
Ignore me (or by all means educate me!) if this is too primitive and uninformed, but my crack at it would be to check for at least one occurrence of a match for:
{"[a-zA-Z].*?":"[a-zA-Z].*?"}
So that's two strings beginning with a letter, enclosed in quotes, separated by a colon, and inside curly brackets.
I also would consider to check after the specific pattern that you like to have as result.
Maybe a good way is including the Keys you expectā¦ this is also what I would do ..
What I definitely would not do is trying to build something that is far too genericā¦ that would then lead into false positives because I didnāt have made the decision to test for the exact thing I expected to have as a result.
Actually, I think I'm wasting my time doing this. I just need more robust error handling at the time of actually parsing the variable, and forget all this up-front checking.
I thought I was making things better, but it's actually making them worse.
Rob youāre the man ā¦ this is truly a powerful way ā¦ and of course - pretty darn simple.
Why havenāt I thought about that ?! - this makes me feel bad actuallyā¦ I think sometimes I should give my ideas a little more time and a little more thinking
Thanks for this wonderful suggestion. Why making things more complicated when they are as simple like that ?!
Rob has a knack for coming up with stuff like this. Don't feel too bad - I've learned to just accept his brilliance and be happy he shares it with us.
I'm being dead serious, by the way. He's one of the good ones. Sometimes his solutions are beyond my comprehension, but that doesn't make them any less brilliant.
I total agree you on that, Dan ā¦ I always take my hat (whenever Iām wearing one) when I see new great stuff from Rob.
I mean these quite impressive coding skills ā¦ the generics stuff he uses in his code every timeā¦ whether itās AppleScript or JXA ā¦
Iāve found someone who writes code in a way I am not able to fully understand and even am not able to learn ā¦ I try my very best - but maybe itās his experience against mineā¦
Anyway - I have a lot of stuff from him as well and I truly love the stuff I have from him ā¦
To Rob (@ComplexPoint) because he is going to read this, too: thanks again for so much good stuff - I take my hat ā¦
You know, I felt the same way until a few weeks ago, when I asked ChatGPT some questions about Rob's code. Specifically:
what does this do: const importedFrom = fNames =>
// eslint-disable-next-line no-new-func
fp => Function(
[
readFile(fp),
return { ${fNames} };
]
.join("\n")
)();
ChatGPT understood exactly what it was doing, and helped me understand it. And then I went down a rabbit trail about Haskell, curried functions, things like that.
Bottom line - it turns out that it's not voodoo. Heh, who knew?
Thatās exactly what I was going through every time I tried again to get behind Robās code ā¦ even without AI and I am not able to get it ā¦ and I donāt know whyā¦
Sometimes I which I had code that would convert the stuff I donāt understand to something that I am able to understand like:
Code with Generics => Code without Generics
The better ā¦ Code that even tells me how it is written in a different languageā¦ like:
Everything you've said is how I've felt for years and years on this forum, when working with Rob's code, so please understand that I get it 100%.
I've always considered myself pretty smart, especially when it comes to programming, but Rob's stuff made me question myself over and over again.
So don't let it get to you, because I know I let it affect me and that didn't help, to say the least!
Here's an aside. I don't put Rob in the following category, but that may be just because I haven't met him face-to-face:
Many moons ago I worked with someone who was so smart, it was like he was beyond human. I told him once that I didn't understand relativity, and he commenced to try to explain it to me right then and there, and was utterly flummoxed when I didn't get it right away. It made me laugh.
Of course, in the intervening years, I have a better grasp of relativity, both general and special, but still - some people are just from another world.
Nothing clever here, just code which defines things, rather than ādoingā things.
If you are used to the latter (imperative code) and try to work out what functional expressions ādoā, then then you may have a hard time
We know what value 2 + 2 defines, but we may scratch our heads and lose some sleep if we start with the wrong question, and try to work out what it ādoesā.
We may tell ourselves:
āFirst I do this, and then I do thatā
but are we really little humunculi running around inside the machine during run-time evaluation of our code?
Or does thinking in those terms just add a redundant layer of confusion and complexity ?
@unlocked2412 is an experienced crafter of expressions which define solutions to problems.
Younger and more energetic than me too ā and I think he does some teaching, if you are curious about functional composition, which is known, empirically, to:
Reduce the rate of bugs, and
increase the speed of code-writing.
then see if @unlocked2412 is available for some teaching.
Faster development, fewer bugs, much less wasted time ā it all boils down to one simple trick:
No mutable names.
In Keyboard Maestro, once youāve bound a name to a value, donāt change the meaning of that name. Never āupdateā an existing variable. New values always get new names
In JavaScript always use const ā not let or var.
Most bugs arise from mutable names,
most of the rest arise from vagueness about the type of value that is bound to a given name.
I am replying so that I can be corrected or otherwise further enlightened..!
I'm curious about what you mean by "defining". I think of functional code has acting upon a value to produce another value ā the same as mathematical "transformation" but where the original is not (unless you explicitly arrange for it) changed or destroyed.
+ 2 is a function that can be applied to a value, x, which in the case of x = 2, results in 4. So we can define our function as something that adds 2 to a value (which is self-evident in terms of mathematical experience ā if not mathematical definition!). We are not defining 4 however. It could be arrived at from an infinite number of other functions.
Nicely put, and a change from the "following a recipe for a cake" analogy. I think it's true to say that KM (especially when thinking of the Editor) most obviously lends itself to the "following a recipe" approach, but awareness of other paradigms can still be of great benefit.
That's really interesting, and something I shall think about.
Even in the syntax of functional languages, an immutable "variable" may be shown as if it were mutable ā e.g. in a simple anonymous function in which x is replied to each of a set of values. In such cases, there is no chance of that x being confused with an x in another function. So bugs involving mutable names arise, I should imagine, from: (1) the programmer losing track of what the variable name currently refers to; (2) scope (which parts of the program can access the variable).
An argument for strong typing, alright.
This discussion has made me curious about the situation that prompted the original question!
I was just trying to do some pre-validation of a parameter. In the long run, I decided against it.
And I will just add that not everyone agrees with some of the points Rob brought up. I have no desire to "get into it" here, but I'll just say that if something sounds extreme, use your own mind and do your own research before you buy into it. And regardless of the particulars here, I'm sure Rob would agree with that.
For each value in the first set (the domain), a given function defines a specific corresponding value in the other set (the codomain).
There's no harm, of course, in introducing mnemonic metaphors of time, transformation, or agency here, but none of them are needed.
If we're looking for helpful metaphors or intuitions, it may be useful to think of a function as a value with a gap.
We know that sqrt n is a value drawn from the complex plane, but there's a gap in it called n
We don't know exactly which value in the codomain set is defined by sqrt n until we fill that gap with a specific value (drawn from the domain set).
sqrt 4 -> 2
sqrt -4 -> 2i
To put it another way, we know the type of sqrt n (the set from which it is drawn),
but only filling an argument slot with a value drawn from the domain set completes the picture,
defining a specific element in that codomain set.