|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 | Next > |
|
|
[scala] Option vs nullAs a vehicle for helping me learn Scala, I have converted one of my
Java programs over to Scala. The Java code included a class with two methods overloading the same name, one with an optional File argument and the other with an optional String argument (representing a file name). The Java methods looked something like this: import java.io.File; public class Test { //f is optional, may be null public void foo(String s, File f) { } //name is optional may be null public void foo(String s, String name) { } } As part of the conversion to Scala, I wanted to use Option objects rather than using null to represent missing values. After converting to Scala, the above code looked something like this: import java.io.File class Test { def foo(s:String, fOpt:Option[File]):Unit = { } def foo(s:String, nameOpt:Option[String]):Unit = { } } However, the compiler gives me the following error message: test.scala:6: error: double definition: method foo:(String,Option[String])Unit and method foo:(String,Option[java.io.File])Unit at line 4 have same type after erasure: (java.lang.String,Option)Unit Is there an elegant solution for this? I could of course change the names so as not to use overloading, or add an argument to one or the other method to disambiguate. I thought about trying to coalesce the two methods into one, but I don't think I can declare an "Option[String or File]" type, and changing it to Option[Any] would weaken type-checking at caller sites. At the moment I have reverted the overloaded methods back to their original signature, accepting a nullable String or File rather than an Option, but I am hoping there is a better "Scala way" solution. There are a couple of small things that could be added to Scala to make it a little simpler to interface to legacy Java code that uses null as a marker for missing data. In particular, it would be convenient to have a "getOrNull" method on Option values when calling into legacy Java code, and to have an easy way to create a None if the raw value returned by legacy Java code is null, or a Some if not null. These two additions would make it a one-step operation to convert each way between an Option value and a maybe-null value. I have implemented these two changes in my code using the following little object: object SomeOrNone { class OptionOrNull[T](x:Option[T]) { def getOrNull():T = if (x.isDefined) x.get else null.asInstanceOf[T] } implicit def optionOrNull[T](x:Option[T]) = new OptionOrNull(x) def apply[T](x:T) = if (x==null) None else Some(x) } I then use "import SomeOrNone" and "import SomeOrNone.optionOrNull" in the source files in which I want to be able to use the SomeOrNone creation method or the getOrNull method on an Option. In order to simplify interfacing to legacy Java code, it would be nice to have the standard Option class include the getOrNull method, and to add an "orNone" constructor to the standard Some object so that I could say "Some.orNone(x)", which would return a None if x were null, else Some(x). I was also a bit surprised to discover that Some(null) is legal. I thought the whole purpose of Option was not to have null values floating around. Perhaps there should also be a Some.notNull(x) constructor that would throw an exception if x==null. -- Jim |
|
|
Re: [scala] Option vs null-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 Jim McBeath wrote: | As a vehicle for helping me learn Scala, I have converted one of my | Java programs over to Scala. The Java code included a class with two | methods overloading the same name, one with an optional File argument | and the other with an optional String argument (representing a file | name). The Java methods looked something like this: | | import java.io.File; | public class Test { | //f is optional, may be null | public void foo(String s, File f) { } | | //name is optional may be null | public void foo(String s, String name) { } | } | | As part of the conversion to Scala, I wanted to use Option objects | rather than using null to represent missing values. After converting | to Scala, the above code looked something like this: | | import java.io.File | class Test { | | def foo(s:String, fOpt:Option[File]):Unit = { } | | def foo(s:String, nameOpt:Option[String]):Unit = { } | } | | However, the compiler gives me the following error message: | | test.scala:6: error: double definition: | method foo:(String,Option[String])Unit and | method foo:(String,Option[java.io.File])Unit at line 4 | have same type after erasure: (java.lang.String,Option)Unit | | Is there an elegant solution for this? I could of course change the | names so as not to use overloading, or add an argument to one or the | other method to disambiguate. I thought about trying to coalesce the | two methods into one, but I don't think I can declare an | "Option[String or File]" type, and changing it to Option[Any] would | weaken type-checking at caller sites. Personally, I'd delete the String function and write a String -> File implicit (if that is not to your liking, I'd abstract it in away such that it does). | | At the moment I have reverted the overloaded methods back to their | original signature, accepting a nullable String or File rather than an | Option, but I am hoping there is a better "Scala way" solution. | | | There are a couple of small things that could be added to Scala | to make it a little simpler to interface to legacy Java code that | uses null as a marker for missing data. In particular, it would be | convenient to have a "getOrNull" method on Option values when calling | into legacy Java code, and to have an easy way to create a None if | the raw value returned by legacy Java code is null, or a Some if | not null. These two functions exists in Scalaz http://projects.workingmouse.com/public/scalaz/artifacts/latest/scaladoc/scalaz/Maybe.html#toNull http://projects.workingmouse.com/public/scalaz/artifacts/latest/scaladoc/scalaz/Option$object.html#onull(A) | | | I was also a bit surprised to discover that Some(null) is legal. I | thought the whole purpose of Option was not to have null values | floating around. Perhaps there should also be a Some.notNull(x) | constructor that would throw an exception if x==null. This discussion has been had. The purpose of Option is not to have null floating around. It just solves that problem by consequence. Similarly, the purpose of a car is not to generate heat from its engine bay. Option is just an algebra like so many others. | | -- | Jim | | | - -- Tony Morris http://tmorris.net/ Real-world problems are simply degenerate cases of pure mathematical problems. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFIdEkUmnpgrYe6r60RAhqYAKDE5SukiFU/YDcDNpJkZ0BON4OxZgCgwYvp oqPgjYQ7TtYbthDNQoTIThU= =7ule -----END PGP SIGNATURE----- |
|
|
[scala] Re: Option vs nullHow about this:
implicit def stringToFile(name : String) = new File(name) /Jesper Nordenberg Jim McBeath wrote: > As a vehicle for helping me learn Scala, I have converted one of my > Java programs over to Scala. The Java code included a class with two > methods overloading the same name, one with an optional File argument > and the other with an optional String argument (representing a file > name). The Java methods looked something like this: > > import java.io.File; > public class Test { > //f is optional, may be null > public void foo(String s, File f) { } > > //name is optional may be null > public void foo(String s, String name) { } > } > > As part of the conversion to Scala, I wanted to use Option objects > rather than using null to represent missing values. After converting > to Scala, the above code looked something like this: > > import java.io.File > class Test { > > def foo(s:String, fOpt:Option[File]):Unit = { } > > def foo(s:String, nameOpt:Option[String]):Unit = { } > } > > However, the compiler gives me the following error message: > > test.scala:6: error: double definition: > method foo:(String,Option[String])Unit and > method foo:(String,Option[java.io.File])Unit at line 4 > have same type after erasure: (java.lang.String,Option)Unit > > Is there an elegant solution for this? I could of course change the > names so as not to use overloading, or add an argument to one or the > other method to disambiguate. I thought about trying to coalesce the > two methods into one, but I don't think I can declare an > "Option[String or File]" type, and changing it to Option[Any] would > weaken type-checking at caller sites. > > At the moment I have reverted the overloaded methods back to their > original signature, accepting a nullable String or File rather than an > Option, but I am hoping there is a better "Scala way" solution. > > > There are a couple of small things that could be added to Scala > to make it a little simpler to interface to legacy Java code that > uses null as a marker for missing data. In particular, it would be > convenient to have a "getOrNull" method on Option values when calling > into legacy Java code, and to have an easy way to create a None if > the raw value returned by legacy Java code is null, or a Some if > not null. These two additions would make it a one-step operation > to convert each way between an Option value and a maybe-null value. > I have implemented these two changes in my code using the following > little object: > > object SomeOrNone { > class OptionOrNull[T](x:Option[T]) { > def getOrNull():T = if (x.isDefined) x.get else null.asInstanceOf[T] > } > > implicit def optionOrNull[T](x:Option[T]) = new OptionOrNull(x) > > def apply[T](x:T) = if (x==null) None else Some(x) > } > > I then use "import SomeOrNone" and "import SomeOrNone.optionOrNull" > in the source files in which I want to be able to use the SomeOrNone > creation method or the getOrNull method on an Option. In order to > simplify interfacing to legacy Java code, it would be nice to have the > standard Option class include the getOrNull method, and to add an > "orNone" constructor to the standard Some object so that I could say > "Some.orNone(x)", which would return a None if x were null, else > Some(x). > > I was also a bit surprised to discover that Some(null) is legal. I > thought the whole purpose of Option was not to have null values > floating around. Perhaps there should also be a Some.notNull(x) > constructor that would throw an exception if x==null. > > -- > Jim > |
|
|
Re: [scala] Option vs nullor:
def foo(s:String, f:Either[File,String]):Unit = { } And then you can match on it. Cheers, -V On Wed, Jul 9, 2008 at 7:13 AM, Tony Morris <tmorris@...> wrote: -----BEGIN PGP SIGNED MESSAGE----- -- Viktor Klang Rogue Software Architect |
|
|
Re: [scala] Option vs nullTony Morris <tmorris@...> wrote:
> Personally, I'd delete the String function and write a String -> File > implicit I sincerely hope you aren't serious. Strings aren't files, and implicitly converting one to the other is a gross sanity violation - consider a lexical analyzer that can scan string text or source from a file (and thus might be overloaded on both): in this case, the string isn't a logical pointer to the file, but rather the other way around, the file is a pointer to the source text. Would you then suggest a File -> String implicit? So that there is an asymmetrical bidirectional conversion between strings and files? > (if that is not to your liking, I'd abstract it in away such > that it does). I don't understand that sentence. (I also wish someone would fix the missing Reply-To header in this mailing list...) -- Barry -- http://barrkel.blogspot.com/ |
|
|
Re: [scala] Option vs null-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 Barry Kelly wrote: > Tony Morris <tmorris@...> wrote: > >> Personally, I'd delete the String function and write a String -> >> File implicit > > I sincerely hope you aren't serious. Strings aren't files, and > implicitly converting one to the other is a gross sanity violation > - consider a lexical analyzer that can scan string text or source > from a file (and thus might be overloaded on both): in this case, > the string isn't a logical pointer to the file, but rather the > other way around, the file is a pointer to the source text. > > Would you then suggest a File -> String implicit? So that there is > an asymmetrical bidirectional conversion between strings and files? > Files" doesn't parse for me because I reason about software using a different method and without labels. The structure of a File (java.io.File) as an algebra is isomorphic to a String (which happens to contradict the statement "Strings aren't Files" - yes they most definitely are!). Given this isomorphism, I have no problem writing an implicit inverse. > >> (if that is not to your liking, I'd abstract it in away such that >> it does). > > I don't understand that sentence. It seems that the OP merely wants function composition with the aforementioned implicit function, however, Scala makes function composition quite laborious (although, as I mentioned on another thread, I have shortened this somewhat). Otherwise, whatever functions are acting over String/File could be abstracted. To answer this more specifically, I'd need to know these functions. > > (I also wish someone would fix the missing Reply-To header in this > mailing list...) > It's been discussed numerous times and I think the conclusion was to leave it as is. I don't know the details because I seem to care less than others do, but you might be interested in looking at these previous threads to get more details. > -- Barry > - -- Tony Morris http://tmorris.net/ Real-world problems are simply degenerate cases of pure mathematical problems. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFIdSmrmnpgrYe6r60RAhvrAJ91rYmSHBu9jTI0JECvt8XDL0ZGUgCgjKNb R4ETLgUBdviPkdVGSQR39Nc= =Y874 -----END PGP SIGNATURE----- |
|
|
Re: [scala] Option vs nullOn 2008-07-09 19:35:36 Barry Kelly wrote:
> > I sincerely hope you aren't serious. Strings aren't files, and > > implicitly converting one to the other is a gross sanity violation > > - consider a lexical analyzer that can scan string text or source > > from a file (and thus might be overloaded on both): No, it shouldn't be. You have two methods that do different things, so they should have different names. (I agree that Tony's implicits are a really dumb idea, just not for this reason.) On 2008-07-10 07:12:12 Tony Morris wrote: > I'm serious (and so is Jesper it seems). The sentence "Strings aren't > Files" doesn't parse for me because I reason about software using a > different method and without labels. The structure of a File > (java.io.File) as an algebra is isomorphic to a String (which happens > to contradict the statement "Strings aren't Files" - yes they most > definitely are!). Given this isomorphism, I have no problem writing an > implicit inverse. This is utter nonsense. If you don't like your sequences of bits being labelled to indicate their purpose, perhaps you should go back and program in BCPL. /J |
|
|
Re: [scala] Option vs nullTony Morris wrote:
> -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Barry Kelly wrote: > > Tony Morris <tmorris@...> wrote: > > > >> Personally, I'd delete the String function and write a String -> > >> File implicit > > > > I sincerely hope you aren't serious. Strings aren't files, and > > implicitly converting one to the other is a gross sanity violation > > - consider a lexical analyzer that can scan string text or source > > from a file (and thus might be overloaded on both): in this case, > > the string isn't a logical pointer to the file, but rather the > > other way around, the file is a pointer to the source text. > > > > Would you then suggest a File -> String implicit? So that there is > > an asymmetrical bidirectional conversion between strings and files? > > > I'm serious (and so is Jesper it seems). The sentence "Strings aren't > Files" doesn't parse for me I think we are speaking in different languages. Here's an explanation of what I mean when I use words like "Strings", "Files", and "is" (plural: "are") (I trust you know what "not" means :) :- "A String" is an instance (i.e. a value) of the java.lang.String class, where the java.lang.String class is intended to represent immutable arrays of characters - i.e. character strings, aka text information. "A File" is an instance of the java.io.File class, where the java.io.File class is intended to represent a file or directory path name. When I use the word "is", I am asserting some level of semantic equivalency between the subject on the left of the "is" and the object on the right, for some context, which itself may be explicit or implied by prior sentences or emails. As in any human language, there is a little fuzziness in here. I hope you are able to follow ;) E.g.: when I say "this String is the path to a file", I am asserting that the *meaning* (in the programmer's mind) of 'this' String value is that it can be interpreted by the OS as the location of a file in some filesystem. So when I say "Strings aren't Files", I am asserting that there isn't a semantic equivalency between Strings and Files. The basis of my claim is that their types have different semantic intent, as documented in the Java platform documentation[1]. Certainly, some Strings may be paths to files, and many Files are paths to files (and not directories, or non-existent files or directories), but I trust a trivial survey of real-life programs will demonstrate that the vast majority of Strings are not employed as paths to files. [1] See: http://java.sun.com/javase/6/docs/api/java/lang/String.html http://java.sun.com/javase/6/docs/api/java/io/File.html I am of course interested in pragmatic concerns over theoretical correspondences; many different things can be mapped to a single set, and each operation shown to be mappable to a corresponding equivalent operation on the single set, and thus be shown to be isomorphic, but this isn't interesting for solving real-world problems. In order for our solutions to help with the real world, the elements of our problem domain need to map onto real objects in the real world, where theoretical correspondences between our abstractions no longer apply. To make that more concrete, let me give an example: - I might use a location for String values called 'name', and intend for that to map to a person in the real world (assuming other constraining factors that remove ambiguity). - I might similarly use a location for File values called 'homeDirectory', and intend for it to map to some range of iron oxide particles contained in a metal box underneath my desk. Now, String and File might have, with appropriate contortions, an isomorphic set of values and operations, but there is in no way a similar isomorphism between a person in the real world and a pile of rust inside a small metal box - at any level humans (who pay software developers their wages) care about. These distinctions (the kinds between Strings and Files) are important in software engineering, because humans are fallible. If everybody used Strings both when they needed names of people and paths for files on disk, there is a danger (because they are fallible, don't forget that) that they might confuse the two somewhere, and mistakenly look for a person inside a metal box, or insult someone by describing them as a bit rusty. This is why I say things like "Strings aren't Files". Because if we go down that path, we have lost a valuable guard against human fallibility. By enabling implicit conversions between Strings and Files, we muddy the gap between the two. And most importantly, because Strings and Files are rarely put to semantically equivalent uses, implicit conversions between the two are ambiguous and conflicting. I tried to make this clear to you by giving you an example; if you create a String -> File implicit conversion, and justify it by appealing to isomorphism, then you can't object to a File -> String conversion that was the inverse. Unfortunately, an alternative obvious File -> String conversion also exists; that of reading the contents of a file on disk into memory as a String; and we have the aforementioned ambiguity and conflict. > because I reason about software using a > different method and without labels. Labels are useful. Function and parameter names are labels. I wonder how successfully you program in the large without named functions or parameters? Even the lambda calculus needs a parameter name! :) > The structure of a File > (java.io.File) as an algebra is isomorphic to a String I have explained why an isomorphism between any two pairs of (set and operations on elements of the set) is not particularly interesting for solutions that people pay wages for - i.e. representing real-world problems - and also why it is important that the distinction between what may theoretically be isomorphic algebras is made clear. In summary, your justification for your suggestion strikes me as naive, narrow-minded and dangerous. It seems to ignore the real world, and the very real complexities of software engineering as practiced professionally. > > (I also wish someone would fix the missing Reply-To header in this > > mailing list...) > > It's been discussed numerous times and I think the conclusion was to > leave it as is. I don't know the details because I seem to care less > than others do, but you might be interested in looking at these > previous threads to get more details. It's unfortunate for me primarily because it breaks threading in my mail reader; and the default action for a reply drops the mailing list from the conversation. The conversation moves from the mailing list folder to my inbox because the sender of the reply is no longer the mailing list, and the mailing list doesn't deliver duplicates when it is CC'd on a reply. As it stands, I don't think I'll be contributing many replies to the Scala mailing list, as I don't want to clog the aforementioned inbox. -- Barry -- http://barrkel.blogspot.com/ |
|
|
Re: [scala] Option vs null-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 Barry Kelly wrote: | Tony Morris wrote: | |> -----BEGIN PGP SIGNED MESSAGE----- |> Hash: SHA1 |> |> Barry Kelly wrote: |>> Tony Morris <tmorris@...> wrote: |>> |>>> Personally, I'd delete the String function and write a String -> |>>> File implicit |>> I sincerely hope you aren't serious. Strings aren't files, and |>> implicitly converting one to the other is a gross sanity violation |>> - consider a lexical analyzer that can scan string text or source |>> from a file (and thus might be overloaded on both): in this case, |>> the string isn't a logical pointer to the file, but rather the |>> other way around, the file is a pointer to the source text. |>> |>> Would you then suggest a File -> String implicit? So that there is |>> an asymmetrical bidirectional conversion between strings and files? |>> |> I'm serious (and so is Jesper it seems). The sentence "Strings aren't |> Files" doesn't parse for me | | I think we are speaking in different languages. Here's an explanation of | what I mean when I use words like "Strings", "Files", and "is" (plural: | "are") (I trust you know what "not" means :) :- | | "A String" is an instance (i.e. a value) of the java.lang.String class, | where the java.lang.String class is intended to represent immutable | arrays of characters - i.e. character strings, aka text information. | | "A File" is an instance of the java.io.File class, where the | java.io.File class is intended to represent a file or directory path | name. | | When I use the word "is", I am asserting some level of semantic | equivalency between the subject on the left of the "is" and the object | on the right, for some context, which itself may be explicit or implied | by prior sentences or emails. As in any human language, there is a | little fuzziness in here. I hope you are able to follow ;) | | E.g.: when I say "this String is the path to a file", I am asserting | that the *meaning* (in the programmer's mind) of 'this' String value is | that it can be interpreted by the OS as the location of a file in some | filesystem. | | So when I say "Strings aren't Files", I am asserting that there isn't a | semantic equivalency between Strings and Files. The basis of my claim is | that their types have different semantic intent, as documented in the | Java platform documentation[1]. Certainly, some Strings may be paths to | files, and many Files are paths to files (and not directories, or | non-existent files or directories), but I trust a trivial survey of | real-life programs will demonstrate that the vast majority of Strings | are not employed as paths to files. | | [1] See: | http://java.sun.com/javase/6/docs/api/java/lang/String.html | http://java.sun.com/javase/6/docs/api/java/io/File.html However, when you analyse the details, you discover an isomorphism of the structure of each algebra. It is bit like saying "construction of logic theorems and computer programming are not the same thing", since they "seem" and "feel" like different things. Indeed, they have different "fuzzy" connotations attached to each. However, fundamentally we *know* they are empirically the same thing (C-H Isomorphism) and that any suggestion that they are different is merely the projection of our own narrow (and prior to the discovery by Curry-Howard, ignorant) views. | | I am of course interested in pragmatic concerns over theoretical | correspondences; many different things can be mapped to a single set, | and each operation shown to be mappable to a corresponding equivalent | operation on the single set, and thus be shown to be isomorphic, but | this isn't interesting for solving real-world problems. In order for our | solutions to help with the real world, the elements of our problem | domain need to map onto real objects in the real world, where | theoretical correspondences between our abstractions no longer apply. | | To make that more concrete, let me give an example: | | - I might use a location for String values called 'name', and intend for | that to map to a person in the real world (assuming other constraining | factors that remove ambiguity). | | - I might similarly use a location for File values called | 'homeDirectory', and intend for it to map to some range of iron oxide | particles contained in a metal box underneath my desk. When you say "intend it to map to ..." I say "define functions across the structure". This is just more accurate reasoning to remove the fuzziness. Once the fuzziness is gone, I'm sure you'll shift your position. That you, personally, to appease yourself and your biases, independently of the software, which exists externally to you, wish to project a different fuzzy meaning on two equivalent structures, is only going to contribute to - at worst - an impoverished view for you of what is really going on. | | Now, String and File might have, with appropriate contortions, an | isomorphic set of values and operations, but there is in no way a | similar isomorphism between a person in the real world and a pile of | rust inside a small metal box - at any level humans (who pay software | developers their wages) care about. WTF? | | These distinctions (the kinds between Strings and Files) are important | in software engineering, because humans are fallible. If everybody used | Strings both when they needed names of people and paths for files on | disk, there is a danger (because they are fallible, don't forget that) | that they might confuse the two somewhere, and mistakenly look for a | person inside a metal box, or insult someone by describing them as a bit | rusty. These fallacious distinctions are *incredibly detrimental* to software development because humans are fallible - even with just my own personal anecdotes over the years. I have met your assertion with my own, which I am committed to as much as you are yours. The question now is, are you prepared to explore this path and possibly shift position? I am, but you'll have to bring some new arguments to the table. | | This is why I say things like "Strings aren't Files". Because if we go | down that path, we have lost a valuable guard against human fallibility. | By enabling implicit conversions between Strings and Files, we muddy the | gap between the two. We have improved our reasoning process by identifying the true structure of our program, instead of artificially and arbitrarily elevating the status of labels that we wish to attach to it. Would you object to me calling this "Option"? How about "Maybe"? sealed trait Null[+A] final case object Nup extends Null[Nothing] final case class Yep[+A](a: A) extends Null[A] What about this? What do you call it? sealed trait Disjunction[+A, +B] final case class OneTheorem(a: A) extends Disjunction[A, Nothing] final case class TheOtherTheorem(b: B) extends Disjunction[Nothing, B] The Scala community agreed that we'd call it "Either", but does it matter? Here are some facts; we can define a covariant functor and a monad across the Null structure. For some other structures, this is not true. Indeed, not for Disjunction! (it is not even well-kinded; we fail immediately). These are just observations about the so-called *real world*. If I were to vanish tomorrow, these observations stand. | | And most importantly, because Strings and Files are rarely put to | semantically equivalent uses, implicit conversions between the two are | ambiguous and conflicting. I tried to make this clear to you by giving | you an example; if you create a String -> File implicit conversion, and | justify it by appealing to isomorphism, then you can't object to a File | -> String conversion that was the inverse. Unfortunately, an alternative | obvious File -> String conversion also exists; that of reading the | contents of a file on disk into memory as a String; and we have the | aforementioned ambiguity and conflict. This fuzzy notion of "semantically equivalent uses" is ill-defined and is unlikely to ever eventuate into a consistent definition. I'm sure you'll try and I'll probably have to respond with a Socratic midwife-like response, until eventually the mailing list gets annoyed with me :) Nevertheless, if I find myself "being fuzzy" or "unable to define consistently under critical examination", either through self-reflection or assistance from peers, then I have a mental defense system that sets off warning bells, which is why I never use such informal reasoning. It misleads us only into states of mental inconsistency. | |> because I reason about software using a |> different method and without labels. | | Labels are useful. Function and parameter names are labels. I wonder how | successfully you program in the large without named functions or | parameters? Even the lambda calculus needs a parameter name! :) Labels are useful, but they denote a structure or concept. The same label for the same structure does not make the structures different, which is at the very essence of the computer program (again, C-H Isomorphism). What label do you attach to this structure? \a b -> b \a b -> a b \a b -> a (a b) \a b -> a (a (a b)) Most people call it "the set of natural numbers". We can run with that. In fact, you can call it "poop" if you like. As long as we have agreement on the structure itself, it is not going to matter to the intangible software. | |> The structure of a File |> (java.io.File) as an algebra is isomorphic to a String | | I have explained why an isomorphism between any two pairs of (set and | operations on elements of the set) is not particularly interesting for | solutions that people pay wages for - i.e. representing real-world | problems - and also why it is important that the distinction between | what may theoretically be isomorphic algebras is made clear. | | In summary, your justification for your suggestion strikes me as naive, | narrow-minded and dangerous. It seems to ignore the real world, and the | very real complexities of software engineering as practiced | professionally. The "real world" where "real complexities" are "practiced professionally"? Oh I know, you mean the one where there are mathematical structures that exist independently of our own biases, yet we feel compelled to project labels on them and pretend that other labels denoting the exact same structure are in some way distinct because we take comfort in our own ignorance? Or, are you talking about a different real world to the one I find myself in? I find the above paragraph quite telling and my sarcasm is not intended to belittle, but display my shock. You're stepping into the land of being blatant with logical fallacy here. To address your statement more bluntly (let's assume good will and not fallaciousness as always), in this real world, software is *seldom practiced professionally*. How many programmers do you know who have none or very little idea about the very basic and essential fundamental tenets of the theory of computation? Since we're on this topic, turn to the person next to you and say "Curry-Howard Isomorphism" (or insert equivalent should you so choose). What response did you attract? I get googley eyes and a "WTF are you talking about?' look. This would be OK, if the respondent had independently discovered this themselves and just not had a label (C-H-I) to attach to it, but I am assuming this is not the case. Now go to your local mechanic and say "spark plug"; same response? Didn't think so. Furthermore, the so-called "real complexities of software engineering" have very little to do with how we label structures. I am fully aware of the deception in industry that dilutes the true contentions in computer programming (like you know, the halting problem for example). In any case, the evidence is all around you. I mean "Java bean"? "Actor"? "LINQ"? Do these words have any meaning at all? For example, a smart programmer looks at LINQ and just says "oh that's a glorified monad". Does this act of "renaming" cause him problems? Actually, quite the opposite - since he can show that they are precisely the same thing (in fact, a specialisation in this case), he can draw on his understanding of *the concept of monads* and fully understand LINQ in the flash of a brief thought. Software is in the abstract, always was and is today - they just don't tell you that at school anymore (I do in my tutorials, but always afterward in spare time where students are keen to learn). Ever wonder why Microsoft hit it so big? Can you really make money with an intangible artifact? The naysayers didn't think so, but at least all parties (Microsoft and the naysayers) were equipped with the knowledge that software is intangible. That we find ourselves in a somewhat altered (distorted?) situation today does not alter this fact. A brief and related thought fondly reminds of the gross ineptitude that surrounded me in my recent, but foregone days working for IBM Software Group :) I won't share it with you, for brevity's sake :) | |>> (I also wish someone would fix the missing Reply-To header in this |>> mailing list...) |> It's been discussed numerous times and I think the conclusion was to |> leave it as is. I don't know the details because I seem to care less |> than others do, but you might be interested in looking at these |> previous threads to get more details. | | It's unfortunate for me primarily because it breaks threading in my mail | reader; and the default action for a reply drops the mailing list from | the conversation. | | The conversation moves from the mailing list folder to my inbox because | the sender of the reply is no longer the mailing list, and the mailing | list doesn't deliver duplicates when it is CC'd on a reply. | | As it stands, I don't think I'll be contributing many replies to the | Scala mailing list, as I don't want to clog the aforementioned inbox. | | -- Barry | I'm out of breath anyway, how about you? :) - -- Tony Morris http://tmorris.net/ Real-world problems are simply degenerate cases of pure mathematical problems. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFIdUvYmnpgrYe6r60RArorAJ0TMXORb5HlaDX2sxpROrL4aRjFFwCfW62u wPU8MlEXSf6UiMgV9v/4lS0= =jYRU -----END PGP SIGNATURE----- |
|
|
Re: [scala] Option vs nullOn Tue, Jul 08, 2008 at 10:02:06PM -0700, Jim McBeath wrote:
> As a vehicle for helping me learn Scala, I have converted one of my > Java programs over to Scala. The Java code included a class with two > methods overloading the same name, one with an optional File argument > and the other with an optional String argument (representing a file > name). Thanks for the suggestions. Tony Morris wrote: > Personally, I'd delete the String function and write a String -> File > implicit (if that is not to your liking, I'd abstract it in away such that > it does). The string I pass in may be a name without a path component, to be turned into a File using a base directory in the object, so I don't think I can define this implicit conversion. > These two functions exists in Scalaz > http://projects.workingmouse.com/public/scalaz/artifacts/latest/scaladoc/scalaz/Maybe.html#toNull > http://projects.workingmouse.com/public/scalaz/artifacts/latest/scaladoc/scalaz/Option$object.html#onull(A) I'm happy to hear that there is a standard solution, but for now I think I will stick to my little object rather than add a dependency to sbaz. It would be nice if the above-referenced doc pages had a one-line description of what each method does. Unfortunately, I am not familiar enough with the terminology used in those classes to understand what all of the methods do based solely on their names and signatures. I will look at the source code if I reach the point of really wanting to know. > This discussion has been had. The purpose of Option is not to have null > floating around. It just solves that problem by consequence. Similarly, > the purpose of a car is not to generate heat from its engine bay. Option > is just an algebra like so many others. Thanks for pointing this out, I will see if I can find these discussions in the archives. Viktor Klang wrote: > def foo(s:String, f:Either[File,String]):Unit = { } > And then you can match on it. An interesting suggestion, but not quite usable for my situation. I want to be able to take an Option value returned by another method that is interfacing to a legacy Java method, and pass that directly back to my method. The combination of the suggestions about using implicit conversions and Either got me thinking about how I might be able to use those two together to do what I want. I have started playing around with various implicit conversions and combinations of Option and Either. I don't yet have a satisfactory solution, but in any case it is helping me with my other goal of learning the language and concepts. The learning is more important to me than the solution for this particular problem. And I am enjoying the continuing discussion about Strings and Files. :-) -- Jim |
|
|
Re: [scala] Option vs nullHi Jim,
my advice: 1. just stay away from implicits 2. do not use overloading instead of Option[Either[File,String]], you could define a special type for your input needs abstract class MyInput case class WithString(s:String) extends MyInput case class WithFile(f:File) extends MyInput case object WithNothing extends MyInput def foo(f: String, bar:MyInput) = bar mach { case ... } foo("bla", WithNothing) hope this helps, Burak On Thu, Jul 10, 2008 at 2:24 AM, Jim McBeath <scala@...> wrote:
-- Burak Emir -- http://burak.emir.googlepages.com |
|
|
[scala] Re: Option vs nullBarry Kelly wrote:
> So when I say "Strings aren't Files", I am asserting that there isn't a > semantic equivalency between Strings and Files. The basis of my claim is > that their types have different semantic intent, as documented in the > Java platform documentation[1]. Certainly, some Strings may be paths to > files, and many Files are paths to files (and not directories, or > non-existent files or directories), but I trust a trivial survey of > real-life programs will demonstrate that the vast majority of Strings > are not employed as paths to files. I agree, but this semantic difference is not enforced in any way by the File class, any string can be mapped to a File object. If you use an invalid file path the compiler/runtime will not complain until you try to access the file. My point is, what additional safety have you achieved by writing "someFileOperation(new File(name))" compared to "someFileOperation(name)"? None. IMO, the methods in the file class could as well be static methods that take the file name as a string parameter. The File class only purpose is to provide a method context which contains the file name. /Jesper Nordenberg |
|
|
Re: [scala] Re: Option vs null |