Hi! My name is Paweł and on this mini blog you can find my random ramblings on programming (ranging from Delphi, JavaScript, .NET to Swift and Clojure) @pol84_
Don't wanna be here? Send us removal request.
Text
If Clojure was a Google product
1) It would be renamed to Glojure to avoid confusion with Google Closure.
2) Consequently, Cursive would be renamed to Gursive.
3) core.async would be a new language, not a library.
4) MS Lisp would be a thing.
5) Apple Lisp would be a thing.
6) Atoms would get patented.
7) The official Glojure editor would display adwords.
8) Google Search would accept s-expressions.
9) Chrome would render hiccup and JIT GlojureScript natively.
10) There would be JavaScript-to-GlojureScript transpilers for migrating older websites.
Disclaimer: Names, characters, businesses, places, events and incidents are either the products of the author's imagination or used in a fictitious manner. Any resemblance to actual persons, living or dead, or actual events is purely coincidental.
0 notes
Text
Curious behaviour of Date type in Chrome
After the last update, Chrome started to differ from other browsers in how it converts UTC time in milliseconds to local time. This is on Windows 10 with UK timezone.
Chrome 67.0.3396.79 Firefox 60.0.2 IE 11.431.16299.0 new Date(70420000000).toString() Sun Mar 26 1972 02:06:40 GMT+0100 (British Summer Time) Sun Mar 26 1972 02:06:40 GMT+0100 (GMT Summer Time) Sun Mar 26 1972 02:06:40 GMT+0100 (GMT Summer Time) new Date(70419000000).toString() Sun Mar 26 1972 01:50:00 GMT+0100 (British Summer Time) Sun Mar 26 1972 00:50:00 GMT+0000 (GMT Standard Time) Sun Mar 26 1972 00:50:00 GMT+0000 (GMT Standard Time) new Date(0).toString() Thu Jan 01 1970 01:00:00 GMT+0100 (Greenwich Mean Time) Thu Jan 01 1970 00:00:00 GMT+0000 (GMT Standard Time) Thu Jan 01 1970 00:00:00 GMT+0000 (GMT Standard Time)
0 notes
Text
Primes again and ‘Apropos Clojure’
I watched & listened to a very cool new Clojure podcast called 'Apropos Clojure' (episode #6). I could not watch the last 15 minutes because was very busy but I continued to listen to it. Of course I was later curious what the final solution was but obviously first had to arrive at it myself with help of what I heard while I was busy.
So my solution is here:
(defn sieve1 [acc [fst & rst]] (lazy-seq (if (some #(divisible? % fst) acc) (sieve acc rst) (cons fst (sieve (conj acc fst) rst)))))
The final solution shown during the show is roughly this:
(defn sieve2 [acc [fst & rst]] (if (some #(divisible? % fst) acc) (recur acc rst) (lazy-seq (cons fst (sieve (conj acc fst) rst)))))
I skipped unimportant differences.
What was surprising to me is that one can use lazy-seq in one of the paths of the function and not all of them. I was just so used seeing it like in my solution. But really why not? It makes sense. Obviously, both solutions gave the same answer and performance-wise seem to be the same on my machine. I was hoping that sieve2 will be faster because it makes fewer calls to lazy-seq but wasn't in my quick testing with time. Still, good to know!
Anyway, I highly recommend this new 'Apropos Clojure' show!
0 notes
Text
Implementing prime functions in Clojure beginning with test.check property-based tests
Starting with the empty function and a most basic test.
(defn primes [n] []) (defspec primes-are-distinct-and-in-correct-number (prop/for-all [n gen/s-pos-int] (let [primes (primes n)] (= n (count primes) (count (distinct primes))))))
This test fails with input of 1.
(defn primes [n] (range n))
Now when it passes, another basic test would be as follows.
(defspec primes-are-natural-and-greater-than-1 (prop/for-all [n gen/s-pos-int] (let [primes (primes n)] (every? (and #(integer? %) #(> % 1)) primes))))
It fails but is easy to pass.
(defn primes [n] (range 2 (+ n 2)))
That out of the way the real test for primes follows.
(defn- prime? [x] (not-any? #(zero? (rem x %)) (range 2 (inc (int (Math/sqrt x)))))) (defspec trial-division (prop/for-all [n gen/s-pos-int] (let [primes (primes n)] (every? prime? primes))))
As expected, it fails with input of 3. Let's try a brute-force method first.
(defn- next-prime [x] (loop [x (inc x)] (if (prime? x) x (recur (inc x))))) (defn primes ([n] (take n (primes))) ([] (iterate next-prime 2)))
It works but probably isn't very fast.
(dotimes [_ 10] (time (doall (primes 250000))))
Not very fast, indeed.
"Elapsed time: 62318.400007 msecs"
Let's try the famous Sieve of Eratosthenes method (with a minor optimization).
(defn- sieve-primes [max-p] (loop [x 2 sieve (set (range x (inc max-p)))] (if (= x max-p) sieve (recur (inc x) (if (sieve x) (reduce disj sieve (range (* x x) (inc max-p) x)) sieve))))) (defn- estimate-nth-prime [n] (-> (* n (+ (Math/log n) (Math/log (Math/log n)) -1)) (* 1.005) (max 2) int)) (defn primes [n] (loop [max-p (estimate-nth-prime n)] (let [ret (sieve-primes max-p)] (if (>= (count ret) n) (take n (sort ret)) (recur (* 2 max-p))))))
Note that Sieve of Eratosthenes returns primes up to a certain number whereas our original primes function returns certain number (count) of primes. This is why we need three functions above - the second and third just estimate the max number and use it to call the first function.
It works but is it much faster?
(dotimes [_ 10] (time (doall (primes 250000))))
It's definitely faster.
"Elapsed time: 21047.096261 msecs"
Another approach is an incremental functional Sieve.
(defn- update-iterators-map [x iterators iterators-map] (-> (reduce (fn [ret iterator] (update ret (+ x iterator) (fnil conj []) iterator)) iterators-map iterators) (dissoc x))) (defn- next-prime [{:keys [x iterators-map]}] (let [x (inc x)] (if-let [iterators (iterators-map x)] (recur {:x x :iterators-map (update-iterators-map x iterators iterators-map)}) {:x x :iterators-map (assoc iterators-map (* x x) [x])}))) (defn primes ([n] (take n (primes))) ([] (map :x (iterate next-prime {:x 2 :iterators-map {4 [2]}}))))
Let's see how it performs.
(dotimes [_ 10] (time (doall (primes 250000))))
It's very close.
"Elapsed time: 21695.772308 msecs"
There is also the Sieve with a small "wheel" (mentioned in Programming Clojure).
0 notes
Text
Using clojure.test.check to help write the least common multiple (LCM) function
This time, too, let's add a stub function and a first test.check spec. In case of the least common multiple, a first spec seems obvious.
(defn lcm [& args] 1) (defspec lcm-is-divisible-by-each-of-args (prop/for-all [args (gen/not-empty (gen/vector gen/s-pos-int))] (let [lcm (apply lcm args)] (every? #(zero? (mod lcm %)) args))))
This fails for the input of [2].
Let's try and pass this test in the easiest way.
(defn lcm [& args] (apply *' args))
It does pass but obviously is not the right solution so we need another test. Something that verifies leastness (even in just simple cases) would be needed.
(defspec lcm-of-a-and-b-where-a-is-divisible-by-b-equals-a (prop/for-all [[a b] (gen/let [b gen/s-pos-int m gen/s-pos-int] [(* b m) b])] (= (lcm a b) a)))
Fails for [2 2]. The easiest method to get our lcm is probably the reduction by the greatest common divisor. This is especially compelling because we've done gcm with help of test.check recently. Note that we're ignoring negative inputs.
(defn gcd [a b] (if (zero? b) a (recur b (mod a b)))) (defn lcm1 [a b] (* (/ a (gcd a b)) b)) (defn lcm [& args] (let [[a b & c] args lcm1 (lcm1 a b)] (if c (recur (cons lcm1 c)) lcm1)))
The test lcm-is-divisible-by-each-of-args fails with NullPointerException for [1]. Right. Let's take care of the singular arguments.
(defn lcm1 [a b] (if b (* (/ a (gcd a b)) b) a))
This time fails with "integer overflow" for [43 17 47 53 41 37 46 52 31 63 61 29]. We need to auto-promote to BigInt.
(defn lcm1 [a b] (if b (*' (/ a (gcd a b)) b) a))
Passes.
We can group it all together as a single function.
(defn lcm [& args] (letfn [(gcd [a b] (if (zero? b) a (recur b (mod a b)))) (lcm1 [a b] (if b (*' (/ a (gcd a b)) b) a))] (let [[a b & c] args lcm1 (lcm1 a b)] (if c (recur (cons lcm1 c)) lcm1))))
0 notes
Text
Fun with dot product and clojure.test.check
Just as before, let's define a placeholder function and a first test. This test is based on the first of dot product properties from Wikipedia.
(defn dot [a b] 0) (defn same-sized-vectors [n generator] (gen/let [m (gen/choose 1 10)] (apply gen/tuple (repeat n (gen/vector generator m))))) (defspec commutative (prop/for-all [[a b] (same-sized-vectors 2 gen/int)] (= (dot a b) (dot b a))))
The current placeholder implementation passes the test, so we need some more tests until hopefully we get a failing one.
(defspec distributive-over-vector-addition (prop/for-all [[a b c] (same-sized-vectors 3 gen/int)] (= (dot a (map + b c)) (+ (dot a b) (dot a c))))) (defspec bilinear (prop/for-all [[a b c] (same-sized-vectors 3 gen/int) r gen/s-pos-int] (let [rb (map (partial * r) b)] (= (dot a (map + rb c)) (+ (* r (dot a b)) (dot a c)))))) (defspec scalar-multiplication (prop/for-all [[a b] (same-sized-vectors 2 gen/int) c1 gen/s-pos-int c2 gen/s-pos-int] (let [** #(map (partial * %) %2)] (= (dot (** c1 a) (** c2 b)) (* c1 c2 (dot a b))))))
All passed by the current placeholder implementation. Let's add a sanity check then.
(defspec sanity-check (prop/for-all [[a b] (same-sized-vectors 2 gen/s-pos-int)] (pos? (dot a b))))
This fails for the smallest input of [1] [1]. Something as simple as returning 1 passes sanity-check and commutative but fails everything else.
(defn dot [a b] 1)
This passes all tests.
(defn dot [a b] (apply + (map * a b)))
0 notes
Text
Using clojure.test.check to write the greatest common divisor (gcd) function
As previously, let's start with a simple placeholder function and a first test.
(defn gcd [a b] a) (defspec both-numbers-are-divisible-by-gcd 100 (prop/for-all [a gen/s-pos-int b gen/s-pos-int] (let [gcd (gcd a b)] (and (zero? (mod a gcd)) (zero? (mod b gcd))))))
This fails for the smallest input of [2 1]. Can we try something else?
(defn gcd [a b] 1)
This passes but also tells us that we need another test, obviously. Fortunately for us, Wikipedia lists GCD properties we can use.
(defspec gcd-of-m-times-a-and-m-times-b-equals-m-times-gcd-of-a-and-b 100 (prop/for-all [m gen/s-pos-int a gen/s-pos-int b gen/s-pos-int] (= (gcd (* m a) (* m b)) (* m (gcd a b)))))
This second test fails for [2 1 1]. Let's try the brute force approach first.
(defn gcd [a b] (loop [div 1 ret 1] (cond (or (> div a) (> div b)) ret (and (zero? (mod a div)) (zero? (mod b div))) (recur (inc div) div) :else (recur (inc div) ret))))
This indeed passes but let's try something smarter - the Euclidean algorithm...
(defn gcd [a b] (cond (> a b) (recur (- a b) b) (< a b) (recur a (- b a)) :else a))
...which can be implemented in an even faster form.
(defn gcd [a b] (if (zero? b) a (recur b (mod a b))))
0 notes
Text
Using clojure.test.check to write a factorial function
Just as the last time, let's add a stub function and a first test.
(defn fact [n] n) (defn gen-tuple-such-that [pred g max-tries] (gen/bind g (fn [left] (gen/tuple (gen/return left) (gen/such-that (partial pred left) g max-tries))))) (defspec fact-n-is-divisible-by-up-to-n 100 (prop/for-all [[div n] (gen-tuple-such-that <= gen/s-pos-int 100)] (zero? (mod (fact n) div))))
This fails for a smallest input of [2 3] which should be easy enough to fix.
(defn fact [n] (if (= n 1) 1 ('* n (fact (dec n)))))
Still fails, but this time for [2 2]. Let's have a look at the REPL.
(fact 2) => 1
Something's not right.
Oops! The ' was on the wrong side of *.
(defn fact [n] (if (= n 1) 1 (*' n (fact (dec n)))))
Now it passes. Let's add another test for a sanity check.
(defn fact-n-equals-fact-dec-n-times-n* [n] (= (fact n) (*' (fact (dec n)) n))) (defspec fact-n-equals-fact-dec-n-times-n 100 (prop/for-all [n gen/s-pos-int] (fact-n-equals-fact-dec-n-times-n* n)))
This fails for 1 with StackOverflowError. Let's try to fix it.
(defn fact [n] (if (<= n 1) 1 (*' n (fact (dec n)))))
Passes. It would be nice to make sure that big factorials can be generated.
(defspec big-fact-n-equals-fact-dec-n-times-n 2 (prop/for-all [n (gen/choose 10000 20000)] (fact-n-equals-fact-dec-n-times-n* n)))
This fails for 10000 with StackOverflowError. It's time for a different approach.
(defn fact [n] (reduce *' 1 (range 1 (inc n))))
Passes. Thank you for your patience!
0 notes
Text
Using clojure.test.check to write Fibonacci numbers generator
Let's start with a stub function and a simple test.
(defn fib [x] x) (defspec fib-is-sum-of-prev-two 10 (prop/for-all [n gen/pos-int] (= (+ (fib n) (fib (+ n 1))) (fib (+ n 2)))))
This fails for input of 0. Let's try to fix it.
(defn fib [x] 0)
Passes. Perhaps time for more tests.
(defspec next-fib-is-bigger-than-prev 10 (prop/for-all [n gen/pos-int] (or (> (fib (inc n)) (fib n)) (= n 1))))
Fails with input of 0.
(defn fib [x] (cond (= x 0) 0 (= x 1) 1 :else (+ (fib (- x 1)) (fib (- x 2)))))
Passes. Let's try something else.
(defrecord tuple [left right]) (defn fib [n] (:right (reduce (fn [ret x] (if (<= x 1) (->tuple (dec x) x) (->tuple (:right ret) (+ (:left ret) (:right ret))))) nil (range (inc n)))))
This tail-recursive version passes, too. It's also quick for big numbers, but you have to replace + with +'.
Also, check out the iter version.
Next time we will look at factorials.
0 notes
Text
Accessing The Noun Project API's from Clojure
Prerequisites: Leiningen & lein-try
$ lein try oauth-clj (use 'oauth.v1 'clojure.pprint) (def client (oauth-client "your key" "your secret" "" "")) (-> {:method :get, :url "http://api.thenounproject.com/icon/1"} client pprint) |{:icon | {:tags | ({:slug "trash", :id 19} | {:slug "garbage", :id 20} | {:slug "litter", :id 21}), | :date-uploaded "", | :uploader-id "", | :uploader "", | :sponsor-campaign-link nil, | :permalink "/term/trash/1", | :license-description "public-domain", | :preview-url-42 "https://d30y9cdsu7xlg0.cloudfront.net/png/1-42.png", | :icon-url | "https://d30y9cdsu7xlg0.cloudfront.net/noun-svg/1.svg?Expires=<blah>", | :collections | ({:description "", | :tags (), | :is-published "1", | :slug "aiga", | :date-created "2012-01-27 19:15:26", | :sponsor-campaign-link "", | :date-updated "2012-09-27 13:27:02", | :name "AIGA", | :permalink "/edward/collection/aiga", | :is-store-item "0", | :template "24", | :author | {:username "edward", | :permalink "/edward", | :name "Edward Boatman", | :location "Los Angeles, US"}, | :id "3", | :sponsor-id "", | :author-id "6", | :is-collaborative "", | :is-featured "1", | :sponsor {}}), | :term-slug "trash", | :term "Trash", | :term-id 19, | :is-active "1", | :year 1974, | :id "1", | :sponsor-id "", | :attribution "Trash from The Noun Project", | :preview-url "https://d30y9cdsu7xlg0.cloudfront.net/png/1-200.png", | :preview-url-84 "https://d30y9cdsu7xlg0.cloudfront.net/png/1-84.png", | :sponsor {}}}
0 notes
Text
The importance of parenthesis is important
I was writing a test case for calculation which involved floating-point numbers. This is was my initial version (C#):
expectedWeight = i * 5000 * (5 / 10) * (7.5 / 14) + i * 10000 * (10 / 5) * (14 / 7.5);
As you can see I added parenthesis to group logically related operations so the code reads better.
Unfortunately the test wasn't passing:
Expected: 37333.332f But was: 38672.6172f
In real application all those numbers that are represented here as literals are floating-point variables.
My initial though was to blame the double/float difference. But the difference between expected and actual values is large and the orders of magnitude that appear in computation are not that different. Therefore, making sure that only doubles are used didn't help. The test was still failing.
I removed parenthesis from the test:
expectedWeight = i * 5000 * 5 / 10 * 7.5 / 14 + i * 10000 * 10 / 5 * 14 / 7.5;
Bingo! The test passed. Do you see what happened here?
Finally, I re-added parenthesis but also made sure that floating-point numbers are inside parenthesis:
expectedWeight = i * 5000 * (5.0 / 10) * (7.5 / 14) + i * 10000 * (10.0 / 5) * (14 / 7.5);
The test passed again. One number type per language can be a good thing.
0 notes
Text
Setting up a spy on an Action<> or a Func<>
If we have a dependency that can be abstracted as a single Action<> or Func<> there is no point (at least more often than not) to create a specific interface.
How to spy on this dependency then?
With NSubstitute it is, it turns out, surprisingly easy:
setClipboard = Substitute.For<Action<string>>(); sut = new SomeSut(setClipboard); sut.CopyAsText(); setClipboard.Received().Invoke("some expected text");
As you would expect, the test will pass if SomeSut.CopyAsText does:
setClipboard("some expected text");
0 notes
Text
Logging JavaScript errors in ASP.NET in three easy steps
If you are like me, you like to know about errors you missed especially those on fussy devices like an iPad. I had this in mind for quite some time to just log all JavaScript errors (I mean in particular app not all on interwebz) but I never actually did it. So I started googling tonight and I found that there is a very good NuGet for this called JSNLog by Matt Perdeck!
Thus this will be very easy. Let's start with a new ASP.NET project (I used MVC 5 but you can use whichever framework you like).
① Run two following commands in Package Manager Console to install NLog and JSNLog:
Install-Package NLog.Config Install-Package JSNLog.NLog
Then open NLog.config and uncomment target and logger elements.
② Open a view file (e.g. Index.cshtml) and add:
@Html.Raw(JSNLog.JavascriptLogging.Configure()) <script src="~/errorlogger.js"></script> <script> window.setTimeout(foo, 1000); function foo() { bar(); } function bar() { throw new Error('bar'); } </script>
(The Html.Raw line is taken from JNLog documentation).
③ Add new file errorlogger.js to project root and paste this (taken from JNLog documentation):
window.onerror = function (errorMsg, url, lineNumber, column, errorObj) { // Send object with all data to server side log, using severity fatal, // from logger "onerrorLogger" JL("onerrorLogger").fatalException({ "msg": "Exception!", "errorMsg": errorMsg, "url": url, "line number": lineNumber, "column": column }, errorObj); // Tell browser to run its own error handler as well return false; };
That's it! If you run the project a bar error should be logged in logs project subfolder as follows (line breaks added):
2014-09-17 22:15:46.3326 FATAL {"stack":"Error: bar at bar (http://localhost:47091/:53:15) at foo (http://localhost:47091/:49:9)", "message":"bar","name":"Error","logData":{"msg":"Exception!", "errorMsg":"Uncaught Error: bar","url":"http://localhost:47091/", "line number":53,"column":15}}
On JSNLog page you can learn that this is a full-blown logging library and is also available for Node.js.
0 notes
Text
Delphi, ANSI Strings, diacritics and Windows 8
This is a quicky. My custom Delphi component caused problem on Windows 8. The Delphi version we are talking about is 2007 and component is not Unicode (is ANSI). The problem is when I copy or paste text with diacritics, even that I have "Language for Non-Unicode programs" Windows setting correctly set to support diacritics in question, diacritics are copied incorrectly and lost on pasting. I haven't this problem on Windows 7 or prior so either this is something fundamental to Windows 8 or just my language settings are bit different than previously (Windows 8 has a new way of configuring those things using some kind of "language profiles").
Nevertheless, the solution was simple. I found out that my component was calling Clipboard.AsText which is ANSI. I simply replaced calls with Clipboard.AsWideText and now it works!
But wait, there is no Clipboard.AsWideText!
You're right. Thankfully I had CopyToWideClipboard procedure in my utils unit. I can't tell the author (I probably got it on Usenet) because unit is really old but here it is:
procedure CopyToWideClipboard(AText: WideString); var Data: THandle; DataPtr: Pointer; Size: Cardinal; begin Size := Length(AText); Data := GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, 2 * Size + 2); try DataPtr := GlobalLock(Data); try Move(PWideChar(AText)^, DataPtr^, 2 * Size + 2); Clipboard.SetAsHandle(CF_UNICODETEXT, Data); finally GlobalUnlock(Data); end; except GlobalFree(Data); raise; end; end;
I didn't have PasteFromWideClipboard but I used TClipboard.GetAsText as a template and here you go:
function PasteFromWideClipboard: WideString; var Data: THandle; begin Clipboard.Open; Data := GetClipboardData(CF_UNICODETEXT); try if Data <> 0 then Result := PWideChar(GlobalLock(Data)) else Result := ''; finally if Data <> 0 then GlobalUnlock(Data); Clipboard.Close; end; end;
0 notes
Text
Inherited public property with protected mutator in .NET Reflection eyes
I found this issue when migrating Windows Phone 7 application to Windows Phone 8. To illustrate the issue, simplified view model looks like this:
public class Sub : Super { public Sub() { MyProperty = "foo bar"; } public override string MyProperty { protected set { base.MyProperty = value; } } } public class Super { public virtual string MyProperty { get; protected set; } }
The view model in use is Sub class which has inherited public MyProperty with protected mutator. This property was bound like this (XAML):
<TextBlock x:Name="PageTitle" Text="{Binding Path=MyProperty}"/>
In Windows Phone 7 this is displayed as "foo bar" but the same app on Windows Phone 8 (either as a WP 7.1 app or as migrated to WP 8) doesn't like this binding:
System.Windows.Data Error: BindingExpression path error: 'MyProperty' property not found on 'Blah.Sub' 'Blah.Sub' (HashCode=51812368). BindingExpression: Path='MyProperty' DataItem='Blah.Sub' (HashCode=51812368); target element is 'System.Windows.Controls.TextBlock' (Name='PageTitle'); target property is 'Text' (type 'System.String')..
Let's make sure this has something to do with reflection:
MessageBox.Show(typeof(Sub).GetProperties().Length.ToString());
Indeed, message says "1" on Windows Phone 7 and "0" on Windows Phone 8.
Let's try full .NET:
var sub = new Sub(); Console.WriteLine(sub.MyProperty); Console.WriteLine(typeof(Sub).GetProperties().Length);
This console application prints same result on each .NET Framework version I have on laptop (2.0 - 4.5.1)
foo bar 0
The result is consistent with WP8. Perhaps WP7 was buggy? This is documentation for parameter-less Type.GetProperties:
Returns all the public properties of the current Type. A property is considered public to reflection if it has at least one accessor that is public.
MyProperty has public accessor. If you doubt it, see that we could read it fine in our console application: Console.WriteLine(sub.MyProperty).
So why it's not returned by parameter-less GetProperties and we have to use overload accepting BindingFlags.NonPublic to get it? Is WP7 right?
The fix is just adding:
get { return base.MyProperty; }
0 notes
Text
Few comments on Swift Programming Language (part V)
This is final part of my wee notes on new programming language from Apple called Swift.
Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil, the property, method, or subscript call returns nil. Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.
I have seen in passing similar feature in Oxygene language. This is convenience feature and as such should be praised but in reality isn't it encouraging to Law of Demeter violating? I can see it being helpful while navigating data structures of some API when doing something quickly in a script or when writing not so good UI code and trying to display some deeply hidden value from data structure but nothing beyond that comes to my mind (I might be missing something though).
let roomCount = john.residence?.numberOfRooms
On the syntax level optional chaining feature feels cheap - you only need to add ? before .. But if you write unit tests, you still need to test this. Thus it's better to write this alternatively so there is less to test. And this code is a violation of rule ('law') mentioned above anyway. Having said that this can be a nice tool when dealing with deeply data-structured external API as stated above and just shouldn't be overused.
Another possible problem with optional chaining I can think of is when you have chain looking like variable.foo?.bar?.field and you are expecting that bar can be nil but foo rather shouldn't be nil but since you are using optional chaining you want to use it here as well - nil is accepted result anyway. Then few months later something changes and foo is nil not as an exception but as a normal business situation which needs to be handled separately. Then you have a problem because when foo is nil the effect will be the same as when bar was nil so you will not get any exception and everything will look okay at a first glance... Obviously this is not be a problem when doing TDD.
if john.residence?.printNumberOfRooms() {
Will control flow enter if body when printNumberOfRooms function will return false? Yes, because all what is required to satisfy this if condition is residence to be assigned. Feels like magic trick although it's in sync with language rules. Still, no magic tricks in language is less bug provoking.
init(name: String, director: String) { self.director = director super.init(name: name) }
It's nice to see you again, the ability to set order of superclass constructor execution (like in Delphi) instead of always executing it before derived class constructor (like in C# and Java). Yes, it can be dangerous but it can be also sometimes useful and the choice simply should be given.
let library = [ Movie(name: "Casablanca", director: "Michael Curtiz"), Song(name: "Blue Suede Shoes", artist: "Elvis Presley") ] // the type of "library" is inferred to be MediaItem[]
Wow, type inferring for collections! Even TypeScript, whose type inferring is very robust, doesn't do it!
if let movie = item as? Movie {
Right, in this example the if let variable = <optional> form impresses with brevity. Note that as? works like as in other languages (safe cast).
An extension can extend an existing type to make it adopt one or more protocols. Where this is the case, the protocol names are written in exactly the same way as for a class or structure:
extension SomeType: SomeProtocol, AnotherProtocol { // implementation of protocol requirements goes here }
This is interesting. Generally extensions in Swift look like a similar idea to extension methods in C# but they can do more things than just attaching methods to type. Some of those things (e.g. 'Provide new initializers', 'Define and use new nested types') are not much helpful as extensions in OO programming so I'll not talk about them. But ability of making an existing type to conform to a protocol (I understand it as making implicit Adapter) sounds very nice and can simplify Adapter writing and using.
The only gotcha is the name itself. People use term 'extension' in C# for example for: extension method, subclass, partial class. Naming language feature just 'extension' doesn't help. But Objective-C name for similar concept ('category') wasn't intuitive neither.
If a class has a superclass, list the superclass name before any protocols it adopts, followed by a comma:
class SomeClass: SomeSuperclass, FirstProtocol, AnotherProtocol {
Syntax is exactly like C#. The only obvious difference: protocol in Swift is what interface is in many other languages. And it seems that Swift is free from 'begin interface name with I' convention.
A protocol can require any conforming type to provide an instance property or type property with a particular name and type.
Speaking of experience of person who did it wrong: in good OO programming you are doing something wrong if you need property on interface. You only should have methods there.
protocol Togglable { mutating func toggle()
In theory it's useful that mutating keyword can be used in interface because it's important information for the caller. However mutating only applies to structures (cannot be used in classes).
I cannot see why one would write interface for structure other than maybe using structure instead of class for it's memory specifics (though that would be misleading perhaps unless used coherently)? I'm just speculating here. Personally I've never written interface for structure although it's possible in C# too and I always use structures only for data structures purpose so I don't need to interface them.
protocol DiceGameDelegate { func gameDidStart(game: DiceGame)
Oh, the Java way. No direct support for events in Swift.
func wishHappyBirthday(celebrator: protocol<Named, Aged>) { println("Happy birthday \(celebrator.name) - you're \(celebrator.age)!") }
Protocol composition (<Named, Aged> in example above) is like telling that instance should implement both (or more) interfaces. In languages without this feature (such as C#, Java) this is often done by making new interface which inherits from two (or more) interfaces. But interface multiplying isn't a good thing. On the contrary - reusable interfaces specific to single task type are good. Thus protocol composition seems like a very good feature in Swift because it promotes usage of well cut interfaces. The only gotcha is that if class implements two interfaces then almost by definition it has too much responsibility.
@objc protocol HasArea {
In order to use as or is operators on the left hand side of protocol you need to use special attribute (@objc) on protocol definition. That's like enabling RTTI for only one type so it is probably optimal but still odd compared to some mainstream languages.
@objc protocol CounterDataSource { @optional func incrementForCount(count: Int) -> Int
The @optional attribute of interface method means that class implementing interface doesn't have to implement this particular method. This is interesting because sometimes when class doesn't implement a method, a dummy method which throws exception is written. This violates Liskov substitution principle. Using @optional instead wouldn't violate it. At least in my opinion. The other matter is whenever interface is well designed if some of its methods is optional in the first place.
if let amount = dataSource?.incrementForCount?(count) { count += amount } else if let amount = dataSource?.fixedIncrement? { count += amount }
In this example the incrementForCount and fixedIncrement are both optional methods. If dataSource is our dependency, shouldn't it do what we ask it for according to our preferences instead of forcing us to query it for implemented methods?
protocol Container { typealias ItemType mutating func append(item: ItemType)
Type alias (typealias ItemType above) is a way of making interfaces generic in Swift. It's disappointing that usual generics syntax (type parameters after name) that works for classes, structures and functions cannot be used for interfaces in Swift.
One interesting rare thing which Swift does is that you don't have to specify concrete (or generic) replacement for type alias in implementation as long as Swift can infer it. Most likely Swift designers thought that this is good reason to move type parameters away from interface name.
func allItemsMatch< C1: Container, C2: Container where C1.ItemType == C2.ItemType, C1.ItemType: Equatable> (someContainer: C1, anotherContainer: C2) -> Bool {
Use of type aliases instead of type parameters implies also different way of specifying constrains on them as can be seen above. The same effect could be achieved in other languages the usual way by declaring three type parameters (two for containers and one for item).
operator prefix +++ {}
The above code defines operator +++ which can be then overloaded by any types as required. This is not only operator overloading but also defining completely custom operators as long as they consist of / = - + * % < > ! & | ^ . ~ characters. Not something we find in C# or Java. Rare feature but do we have real good use for it? Badly used operator overloading can obviously be very misleading. Maybe rightful introduction of new operators will not be that bad as long as they differ visually enough from existing operators and are used consistently in project.
Thanks for reading. Head over here to read the previous comments on Swift.
0 notes
Text
Few comments on Swift Programming Language (part IV)
This is continuation of three previous comments on the Swift language.
The capabilities described above for computing and observing properties are also available to global variables and local variables. Global variables are variables that are defined outside of any function, method, closure, or type context.
World is fine without global variables, no need to go there again.
However, you can also define computed variables and define observers for stored variables, in either a global or local scope. Computed variables calculate rather than store a value, and are written in the same way as computed properties.
Why not just write a method?
For value types (that is, structures and enumerations), you can define stored and computed type properties. For classes, you can define computed type properties only.
Lets forget for a moment about existence of computed properties and think only about stored properties. What you can read above is very surprising. It seems at a first glance that this should be the other way around. But think about it. Structures are to hold data. If you really need (in these rare situations) to hold static data, hold it in a structure. Keep classes free of static data. Bravo!
Methods in Swift are very similar to their counterparts in Objective-C. As in Objective-C, the name of a method in Swift typically refers to the method’s first parameter using a preposition such as with, for, or by, as seen in the incrementBy method from the preceding Counter class example. The use of a preposition enables the method to be read as a sentence when it is called.
This is something I like very much. It just makes sense for reasons I mentioned in previous parts.
The second argument, however, is qualified by an external parameter name to make its purpose clear when the method is called. This default behavior effectively treats the method as if you had written a hash symbol (#) before the numberOfTimes parameter: func incrementBy(amount: Int, #numberOfTimes: Int) {
So by default the call will have (?) to look either incrementBy(5, numberOfTimes: 10) or incrementBy(amount: 5, numberOfTimes: 10). It should be like this in every language!
Structures and enumerations are value types. By default, the properties of a value type cannot be modified from within its instance methods. However, if you need to modify the properties of your structure or enumeration within a particular method, you can opt in to mutating behavior for that method.
Constants department is excels again!
mutating func moveByX(deltaX: Double, y deltaY: Double) { self = Point(x: x + deltaX, y: y + deltaY) }
This is one of those things in Swift. What this code does is just reninitalization of structure from itself. Why?
subscript(index: Int) -> Int { get { // return an appropriate subscript value here } set(newValue) { // perform a suitable setting action here } }
This syntax for handling index operator (subscript in Swift) looks elegant and is just a mixture of C# solution to same problem and TypeScript way of declaring return type. It's hard to not like it but indexes are not that often defined for custom types.
A class or structure can provide as many subscript implementations as it needs, and the appropriate subscript to be used will be inferred based on the types of the value or values that are contained within the subscript braces at the point that the subscript is used.
Allowing and supporting this is not the best idea in my opinion because of it's threat to code expressiveness.
The next code snippet defines three variables of type Person?, which are used to set up multiple references to a new Person instance in subsequent code snippets. Because these variables are of an optional type (Person?, not Person), they are automatically initialized with a value of nil, and do not currently reference a Person instance. var reference1: Person?; var reference2: Person?; var reference3: Person?;
Two interesting thing there.
It looks like you need to use optional to be able to assign nil to reference type variable. So no optional means no nil as a valid value for reference type variable? That's really good. If existence of optionals allows me to control this, I'm officially a little bit less pained with optionals.
Local variable was automatically initialized with default value. Normally it's the instance variable who is automatically initialized with default and local who is not but Swift is different.
Because a weak reference does not keep a strong hold on the instance it refers to, it is possible for that instance to be deallocated while the weak reference is still referring to it. Therefore, ARC automatically sets a weak reference to nil when the instance that it refers to is deallocated. You can check for the existence of a value in the weak reference, just like any other optional value, and you will never end up with a reference to an invalid instance that no longer exists.
Automatically sets to nil. This is very nice feature. No one likes these memory access errors!
Like weak references, an unowned reference does not keep a strong hold on the instance it refers to. Unlike a weak reference, however, an unowned reference is assumed to always have a value. Note also that Swift guarantees your app will crash if you try to access an unowned reference after the instance it references is deallocated. You will never encounter unexpected behavior in this situation. Your app will always crash reliably, although you should, of course, prevent it from doing so.
Another very nice feature. It's much easier to find a bug when application will always crash on memory access violation rather than have random behavior depending on current memory state which makes it one of my favourite Swift features.
Place the capture list before a closure’s parameter list and return type if they are provided: @lazy var someClosure: (Int, String) -> String = { [unowned self] (index: Int, stringToProcess: String) -> String in
So if you want to use capture list in closure (to break ARC reference cycle) you bet the closure is parameterless otherwise Swift requires typing parameter list (types) two times.
@lazy var someClosure: () -> String = { [unowned self] in
That's better but still, Swift, can't you just automatically treat self as a weak reference in closures assigned to instance as per declaration? If someone just returns closure from a method that's fine, use strong reference. I just don't like to repeat this [unowned self] in each time. Better (because shorter) than [unowned self] in would be also @lazy var someClosure: (self) -> String = { if you need to be a little explicit, Swift.
0 notes