Found it! (Somehow the good ideas always come after asking others for help.) I forgot to make the MyClass constructor public. I'm still curious to learn what this error message means, or why F# is looking for the backquote-number class.
Names like
TypeName`N
are the way the CLR represents
TypeName<Arg1,Arg,...ArgN>
under the hood. You'll see these kinds of names exposed through a number of APIs and diagnostics throughout the .Net platform, so it's useful to know that it just means 'the generic version of that type that takes N generic parameters'.
And I should note that you'll live a longer, happier life if you write
1 2 3 4
type t(a,b) = inherit MyClass<string,int>(a,b) member x.SayHello = System.Console.WriteLine("Hello!")
instead. Avoid the form of classes that lack constructor parens right after the type declaration and that use explicit fields.
[I apologize for any mis-understandings below -- even RTFM isn't very explict about these issues. And when I refer to "I", I also mean "someone reading the code" that may not have been the author.]
> Avoid the form of classes that lack constructor parens right after the type declaration
The problem I have with this is that (at least at the moment) I'm not sure what the object footprint is that I'm actually creating. In:
1 2 3
type t(a:int,b:int) = member x.SayHello = System.Console.WriteLine("Hello!")
Because "a" and "b" are not used anywhere, are "a" and "b" actually part of the object or not?
Or are they just initalizers for the default c'tor? I'm not even sure what the "spirit" of this construct is -- from the "lightweight object" perspective (like f#/ocaml Records), I'd expect "a" and "b" to be part of the object, but from an .Net perspective, I would not, and I'd expect "a" and "b" to be just "optimized-away" in the above case. (There is no compiler warning to suggest that "a" and "b" are never referenced and are therefore being thrown away.) I'm pretty sure that at the moment, these are "real" object slots, but in the future, could they be optimized-away? (Would need to know if I were going to use reflection, etc.)
The documentation's explanation of "a" and "b":
The <i>parameter-list<i> describes constructor parameters
Leads one to the wrong conclusion - they are not simply c'tor parameters, but member slot declarations.
Now if I have:
<code lang=fsharp>type t(a,b) =
member x.SayHello =
System.Console.WriteLine("Hello!" + a.ToString() )</code>
I know that "a" is part of the object, given that it compiles and there's no other "a" hanging around.
With:
<code lang=fsharp>type t(a,b) =
inherit MyClass<string,int>(a,b)
let aa = a
member x.SayHello =
System.Console.WriteLine("Hello!" + aa.ToString() )</code>
It's again a little confusing, because it looks like "aa" should be "closed over" the member function, but becuase the member function declaration isn't a functional construct, I'm again not sure what is going on.
Is "aa" a slot or an alias for "a"? If it's the former, seeing neither is mutable, I'm really wasting 4 bytes, and again, there's no compiler warning that says "warning: slots 'a' and 'aa' will always refer the the value of 'a' at the time of construction (barring use of reflection)" -- could the compiler throw one of these slots away and simply make "aa" an alias for "a"?
Over and over the f# tutorials tell the new user that "In let x', 'x' isn't a variable, it's just a binding!" - but here we've allocated storage - I'm not sure what the rational was for overloading "let" in this way, when they could have just allowed "vals" to be initalized. (Though I'm sure there was a good reason.) (Maybe just being explicit and saying "slot" or "obj"?)
Now, if I hover over these in the editor, they both do say "val" -- so it would seem I have a hint that they are both slots. But consider:
<code lang=fsharp>type t(a:string) =
let aa = a
member x.SayHello =
let aaa = aa
System.Console.WriteLine("Hello!" + aaa.ToString() )</code>
Now "aaa" is still id still "val" in the hover, but we don't have an object slot here, just a local binding, so the tip wasn't really that helpful. (From a type-system perspective they are all "val:string", but "aaa" is a very different thing from "a" and "aa" - again "val" seems like a strange choice to create and name an object slot.)
Identifier syntax coloring based on slot vs. let-binding could be helpful here.
Although I appreciate brevity, at least if I see "val" I know there's a there there...
thanks
A few quick notes.
All 'let' bindings say 'val' in the tooltips. 'val' has nothing to do with 'field' in this context, that's just what tooltips display for showing the types of identifiers.
The F# spec here about 'what becomes fields' is subject to change up until VS2010 releases. The spec is also thin in describing this (and lots of other stuff; we have a lot of spec work to do).
If you really care about 'what becomes a field', then you may prefer the 'explicit' syntax with val. But 99% of the time I think you ought not care (only if you're very deep into perf, in which case you maybe should be using structs instead of classes anyway).
> All 'let' bindings say 'val' in the tooltips. 'val' has nothing to do with 'field' in this context, that's just what tooltips display for showing the types of identifiers.
That's what I was trying to say. But if the tooltips <i>always <i>say "val" then there isn't much meaning to the word and we may as well see "aaa: string" rather then "val aaa: string". However, I'd rather have it tell me more, in this case that's it's an object field. > The F# spec here about 'what becomes fields' is subject to change up until VS2010 releases. The spec is also thin in describing this (and lots of other stuff; we have a lot of spec work to do). Thanks for this response -- at least I don't feel so bad now... :) This is where I was coming from -- I didn't mean to say that one couldn't write some boilerplate code and bring up relector everytime you had a question about what was going on, but that it shouldn't be necessary - and I'm sure the docs (and I) will be straightned out. > If you really care about 'what becomes a field', then you may prefer the 'explicit' syntax with val. But 99% of the time I think you ought not care (only if you're very deep into perf, I'm not sure I agree that you have to be "very deep into perf" to "care what becomes a field" -- this seems like a rather germane concept and way "above the radar" on the abstraction scale, especially for a .Net language that's on the CLR and interops with all sorts of other code. Making unneeded fields can effect perf (large objects), and not having needed fields can effect interop (reflection), so there's no perfect default, but the current non-field status of un-used primary c'tor args seems like the right one here - reflection is pretty advanced and using val here seems fine. But if this is "subject to change" past the release, there certainly should be a big warning in the docs that user object sizes could vary greatly with some future release. > in which case you maybe should be using structs instead of classes anyway). This is not the case for many c# programs due to copy overhead of structs over refs, except for gobs of > gen 0 objects, right? -- is there something about f# that makes this choice different? I love f# (have used it at work and at play) and am coming from that place, not trying to complain...
I'm not sure I agree that you have to be "very deep into perf" to "care what becomes a field" -- this seems like a rather germane concept and way "above the radar" on the abstraction scale, especially for a .Net language that's on the CLR and interops with all sorts of other code. Making unneeded fields can effect perf (large objects), and not having needed fields can effect interop (reflection), so there's no perfect default, but the current non-field status of un-used primary c'tor args seems like the right one here - reflection is pretty advanced and using val here seems fine. But if this is "subject to change" past the release, there certainly should be a big warning in the docs that user object sizes could vary greatly with some future release.
> in which case you maybe should be using structs instead of classes anyway).
This is not the case for many c# programs due to copy overhead of structs over refs, except for gobs of > gen 0 objects, right? -- is there something about f# that makes this choice different?
Yes, sounds like you're right about the perf/reflection/etc trade-offs here (I was trying to summarize too much in a sentence; there is nothing differenc/special about F# when it comes to choosing between structs and classes and whatnot).
The intention/expectation is that by the time VS2010 releases that there will be a fixed spec regarding 'what are the guarantees about what turns into a field' as well is 'if there is any implementation flexibility when it comes to optimizing away fields' (e.g. stuff that could change, either from build to build, or in future versions of the language/compiler).
(My understanding is that the thing that concerns you more is that eventually you want to be ensured that there will be a mechanism to predict/understand/control what become fields, moreso than the particular details of 'what are the rules that say whether this particular let-bound thing or constructor param becomes a field or not' - yes?)
> The intention/expectation is that by the time VS2010 releases that there will be a fixed spec...
Sounds great...
> ...eventually you want to be ensured that there will be
> a mechanism to predict/understand/control what become fields, moreso than...
Well, as for "predict/understand" - certainly, but sounds like that will be taken care of already by the above. As for "control", I'm happy knowing what's going on, and being able to do things the "old-fashioned way" if I'm not sure. Tools support (tooltips, identifier coloring/format, diagrams, etc.) is also great.
Denotational abstraction is awsome (I'm all for less typing...), as long as predictability doesn't suffer too much - but I suppose one should expect and thrive in a certain amount of TMTOWTDI in f# given it's position.
even RTFM isn't very explict about these issues.
In this particular circumstance "the manual" is <a href=http://research.microsoft.com/apps/pubs/default.aspx?id=79948>The F# Draft Language Specification</a> in particular section "8.5 Class Types". <code lang=fsharp>type t(a:int,b:int) = member x.SayHello = System.Console.WriteLine("Hello!")</code> t(a:int,b:int) isn't just a constructor - it is the [i]primary constructor[/i]. As such the declaration (a:int,b:int) doesn't just contain constructor parameters but also the fields in the object (additional fields can still be added in the type definition). Current generation functional (hybrid) languages are trying to dispense with the boilerplate code and high ceremony that is so common in languages like Java or C# - type inferencing is the most notable measure but other shortcuts, like primary constructors, are scattered throughout. If you assume immutability by default, it makes sense to assume for the [i]general[/i] and most likely case that the constructor parameter list is identical to the object field layout. <code lang=fsharp>type PairOfIntegers(x:int,y:int) = new (x) = PairOfIntegers(x,x)</code> PairOfIntegers(x:int,y:int) is the primary constructor of a class that defines fields x:int, and y:int in its instances. PairOfIntegers(x) is an [i]additional object constructor[/i] that initializes both x and y fields to the value of the parameter "x". <code lang=fsharp>type PairOfStrings = val s1 : string val s2 : string new (s) = { s1 = s; s2 = s } new (s1,s2) = { s1 = s1; s2 = s2 }</code> PairOfStrings doesn't define a primary constructor - therefore the object fields have to be defined separately. PairOfStrings does define two "additional object constructors". However given the advice in this topic you should stick with: <code lang=fsharp>type PairOfStrings(s1:string,s2:string) = new (s) = PairOfStrings(s,s)</code> When a primary constructor is present, additional constructors have to use the primary or other additional constructors - so ultimately the primary constructor will always be used in the construction of any object instance in the class.
> Current generation functional (hybrid) languages are trying to dispense with the boilerplate code and high ceremony that is so common in languages like Java or C#
A great thing! - until it becomes less self-documenting (not to mention messier looking, harder to comment/XML-document, etc.) rather than more - if I glance at a class and need to look for primary c'tors, top-level let's (being careful to avoid any deeper ones), etc., then my job becomes harder as code-reader, if not for the code-writer. Luckily, tools are coming to the rescue, and if I can bring up a pretty WPF-rendered view of the class with one keystroke, it's all good.
> If you assume immutability by default, it makes sense to assume for the general and most likely case that the constructor parameter list is identical to the object field layout.
But, aren't records exactly the solution for these "bags of values"?
If you want state+behavior and are opening the door for interop, then it seems like defining your classes longhand seems the most clear.
Hopefully there will also be f# refactorings for these classes of problems. ( "Refactor->Convert vals to primary ctor", backwards again, etc.)
until it becomes less self-documenting
(not to mention messier looking, harder to comment/XML-document, etc.)
rather than more ... tools are coming to the rescue...
The problems that you are describing are related to the terseness of
many functional languages that goes hand in hand with their
expressiveness. The "longhand" of C# is helpful for beginners and
intermediate programmers but can become "unnecessary noise" for the
more advanced programmer - noise which could bury some important bits.
Also the boiler plate code can become a real drag on productivity as
evidenced by the multitude of features in development tools that
"helpfully" insert the "longhand" for you. Many functional languages
have preferred to let the context imply the boiler plate rather than
having to insert it.
Of course as a consequence code with "boiler plate implied by context"
is harder to read for a novice - probably one of the reasons why some
languages that use the approach experience a relatively slow (and low)
rate of adoption. This is really where the development tools need to
catch up and make the implied information more visible for non-experts
to ease the learning curve - showing the inferred types is only the
first step.
If you want state+behavior and are opening
the door for interop, then it seems like defining your classes longhand
seems the most clear.
Don't forget that F# is still primarily a functional language and isn't
meant to replace C#. So the object oriented constructs exist to a large
extent to enable interop. The syntax, semantics and sensibilities for
defining the OO constructs need to "fit" into the functional world of
F# - which includes "being terse" to reduce "redundant" information as
much as possible, enabling more expressive code (which is also compact;
compact code on the other hand isn't necessarily expressive).
I made this class here:
1 2 3 4 5
type t(a:int,b:int,c:int) = let bb = b member x.SayHello() = System.Console.WriteLine("Hello! " ^ a.ToString()) member x.B = bb
and if we put it through Reflector, we get this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
[Serializable, CompilationMapping(SourceConstructFlags.ObjectType)] public class t { // Fields internal int a; internal int bb; // Methods public t(int a, int b, int c) { Program.t @this = this; @this.a = a; @this.bb = b; } public void SayHello() { Console.WriteLine(Operators.op_Concatenate("Hello! ", this.a.ToString())); } // Properties public int B { get { return this.bb; } } }
Thus it appears that constructor parameters that are used non-constructor code become fields and other constructor parameters don't.
Thus it appears that constructor parameters that are used non-constructor code become fields and other constructor parameters don't.
This could just as easily be the result of an "elimination of unused fields" optimization. For the time being I'm going to assume that the [i]intent[/i] behind the primary constructor's parameter list is to:
- specify the constructor's object initialization values
- specify the user settable fields for all object instances (other "computable" fields can still be added further into the type definition)
Avoid the form of classes that lack constructor parens right after the type declaration…
Why is that? Is that going away from the language? I may be missing something but that should be the only way to declare a non-public constructor.
No, you can make the primary constructor private, a la
1 2 3 4
type t private(a,b) = // note 'private' inherit MyClass<string,int>(a,b) member x.SayHello = System.Console.WriteLine("Hello!")
It's not going away from the language, but it's the preferred form, and 99% of code you'll find will use the preferred form. The syntax for the other form is ugly (especially with regards to fields/constructors/inheritance/initialization).
…you can make the primary constructor private…
Thanks, I did not know that syntax. Cool!
Topic tags
- f# × 3705
- websharper × 1897
- compiler × 286
- functional × 201
- ui next × 139
- c# × 121
- classes × 97
- web × 97
- .net × 84
- book × 84
- async × 76
- ui.next × 67
- bug × 54
- core × 49
- website × 49
- server × 45
- parallel × 43
- ui × 43
- enhancement × 41
- parsing × 41
- testing × 41
- trywebsharper × 41
- typescript × 37
- html × 35
- javascript × 35
- owin × 35
- asynchronous × 30
- monad × 28
- ocaml × 28
- tutorial × 27
- warp × 27
- haskell × 26
- sitelet × 25
- linq × 22
- workflows × 22
- wpf × 20
- fpish × 19
- introduction × 19
- silverlight × 19
- sitelets × 19
- monodevelop × 17
- rpc × 17
- suave × 17
- piglets × 16
- collections × 15
- feature request × 15
- jquery × 15
- templates × 15
- getting started × 14
- pipeline × 14
- kendoui × 13
- reactive × 12
- 4.1.0.171 × 11
- monads × 11
- opinion × 10
- 4.0.190.100-rc × 9
- deployment × 9
- fixed × 9
- formlets × 9
- in × 9
- json × 9
- plugin × 9
- proposal × 9
- scheme × 9
- solid × 9
- basics × 8
- concurrent × 8
- highcharts × 8
- how-to × 8
- python × 8
- 4.1.1.175 × 7
- complexity × 7
- documentation × 7
- visual studio × 7
- 4.1.2.178 × 6
- lisp × 6
- real-world × 6
- released in 4.0.192.103-rc × 6
- remoting × 6
- resources × 6
- scala × 6
- websharper ui.next × 6
- workshop × 6
- xaml × 6
- 4.0.193.110 × 5
- 4.2.3.236 × 5
- aspnetmvc × 5
- authentication × 5
- azure × 5
- bootstrap × 5
- conference × 5
- dsl × 5
- formlet × 5
- java × 5
- list × 5
- metaprogramming × 5
- ml × 5
- released in Zafir.4.0.188.91-beta10 × 5
- sql × 5
- visualstudio × 5
- websharper.forms × 5
- zafir × 5
- 4.0.192.106 × 4
- 4.0.195.127 × 4
- 4.1.0.38 × 4
- 4.2.1.86 × 4
- 4.2.6.118 × 4
- css × 4
- example × 4
- extensions × 4
- fsi × 4
- fsx × 4
- html5 × 4
- jqueryui × 4
- lift × 4
- reflection × 4
- remote × 4
- rest × 4
- spa × 4
- teaching × 4
- template × 4
- websocket × 4
- wontfix × 4
- 4.0.196.147 × 3
- 4.1.0.34 × 3
- 4.1.6.207 × 3
- 4.2.1.223-beta × 3
- 4.2.11.258 × 3
- 4.2.4.114 × 3
- 4.2.4.247 × 3
- 4.2.5.115 × 3
- 4.2.6.253 × 3
- 4.2.9.256 × 3
- ajax × 3
- alt.net × 3
- aml × 3
- asp.net mvc × 3
- canvas × 3
- cloudsharper × 3
- compilation × 3
- database × 3
- erlang × 3
- events × 3
- extension × 3
- file upload × 3
- forums × 3
- inline × 3
- issue × 3
- kendo × 3
- macro × 3
- mono × 3
- msbuild × 3
- mvc × 3
- pattern × 3
- piglet × 3
- released in Zafir.4.0.187.90-beta10 × 3
- svg × 3
- type provider × 3
- view × 3
- 4.1.1.64 × 2
- 4.1.5.203 × 2
- 4.1.7.232 × 2
- 4.2.10.257 × 2
- 4.2.3.111 × 2
- 4.2.5.249 × 2
- android × 2
- asp.net × 2
- beginner × 2
- blog × 2
- chart × 2
- client × 2
- client server app × 2
- clojure × 2
- computation expressions × 2
- constructor × 2
- corporate × 2
- courses × 2
- cufp × 2
- d3 × 2
- debugging × 2
- direct × 2
- discriminated union × 2
- docs × 2
- elm × 2
- endpoint × 2
- endpoints × 2
- enterprise × 2
- entity framework × 2
- event × 2
- f# interactive × 2
- fable × 2
- flowlet × 2
- formdata × 2
- forms × 2
- fsc × 2
- google maps × 2
- hosting × 2
- http × 2
- https × 2
- iis 8.0 × 2
- install × 2
- interactive × 2
- interface × 2
- iphone × 2
- iteratee × 2
- jobs × 2
- jquery mobile × 2
- keynote × 2
- lens × 2
- lenses × 2
- linux × 2
- listmodel × 2
- mac × 2
- numeric × 2
- oauth × 2
- obfuscation × 2
- offline × 2
- oop × 2
- osx × 2
- packaging × 2
- pattern matching × 2
- performance × 2
- pipelines × 2
- q&a × 2
- quotation × 2
- reference × 2
- released in Zafir.4.0.185.88-beta10 × 2
- rx × 2
- script × 2
- security × 2
- self host × 2
- seq × 2
- sockets × 2
- stm × 2
- tcp × 2
- trie × 2
- tutorials × 2
- type × 2
- url × 2
- var × 2
- websharper.charting × 2
- websharper4 × 2
- websockets × 2
- wig × 2
- xna × 2
- zh × 2
- .net interop × 1
- 2012 × 1
- 4.0.194.126 × 1
- 4.1.3.184 × 1
- 4.1.4.189 × 1
- 4.2.0.214-beta × 1
- 4.2.12.259 × 1
- 4.2.2.231-beta × 1
- 4.2.8.255 × 1
- Canvas Sample Example × 1
- DynamicStyle Animated Style × 1
- Fixed in 4.0.190.100-rc × 1
- Released in Zafir.UI.Next.4.0.169.79-beta10 × 1
- SvgDynamicAttribute × 1
- WebComponent × 1
- abstract class × 1
- accumulator × 1
- active pattern × 1
- actor × 1
- addin × 1
- agents × 1
- aggregation × 1
- agile × 1
- alter session × 1
- animation × 1
- anonymous object × 1
- apache × 1
- api × 1
- appcelerator × 1
- architecture × 1
- array × 1
- arrays × 1
- asp.net 4.5 × 1
- asp.net core × 1
- asp.net integration × 1
- asp.net mvc 4 × 1
- asp.net web api × 1
- aspnet × 1
- ast × 1
- attributes × 1
- authorization × 1
- b-tree × 1
- back button × 1
- badimageformatexception × 1
- bash script × 1
- batching × 1
- binding-vars × 1
- bistro × 1
- body × 1
- bundle × 1
- camtasia studio × 1
- cas protocol × 1
- charts × 1
- clarity × 1
- class × 1
- cli × 1
- clipboard × 1
- clojurescript × 1
- closures × 1
- cloud × 1
- cms × 1
- coding diacritics × 1
- color highlighting × 1
- color zones × 1
- combinator × 1
- combinators × 1
- compile × 1
- compile code on server × 1
- config × 1
- confirm × 1
- content × 1
- context × 1
- context.usersession × 1
- continuation-passing style × 1
- coords × 1
- cordova × 1
- cors × 1
- coursera × 1
- cross-domain × 1
- csla × 1
- current_schema × 1
- custom content × 1
- data × 1
- data grid × 1
- datetime × 1
- debug × 1
- declarative × 1
- delete × 1
- devexpress × 1
- dhtmlx × 1
- dictionary × 1
- directattribute × 1
- disqus × 1
- distance × 1
- do binding × 1
- doc elt ui.next upgrade × 1
- docker × 1
- dojo × 1
- dol × 1
- dom × 1
- domain × 1
- du × 1
- duf-101 × 1
- dynamic × 1
- eastern language × 1
- eclipse × 1
- edsl × 1
- em algorithm × 1
- emacs × 1
- emotion × 1
- enums × 1
- error × 1
- etw × 1
- euclidean × 1
- eventhandlerlist × 1
- examples × 1
- ext js × 1
- extension methods × 1
- extra × 1
- facet pattern × 1
- failed to translate × 1
- fake × 1
- fantomas × 1
- fear × 1
- float × 1
- form × 1
- form-data × 1
- forum × 1
- fp × 1
- frank × 1
- fsdoc × 1
- fsharp × 1
- fsharp.core × 1
- fsharp.powerpack × 1
- fsharpx × 1
- fsunit × 1
- function × 1
- functional style × 1
- game × 1
- games × 1
- gc × 1
- generic × 1
- geometry × 1
- getlastwin32error × 1
- getting-started × 1
- google × 1
- google.maps × 1
- grid × 1
- group × 1
- guide × 1
- hash × 1
- headers × 1
- hello world example × 1
- heroku × 1
- highchart × 1
- history × 1
- how to × 1
- html-templating × 1
- http405 × 1
- httpcontext × 1
- hubfs × 1
- i18n × 1
- ie 8 × 1
- if-doc × 1
- iis × 1
- image × 1
- images × 1
- inheritance × 1
- initialize × 1
- input × 1
- install "visual studio" × 1
- installer × 1
- int64 × 1
- interfaces × 1
- internet explorer × 1
- interop × 1
- interpreter × 1
- io × 1
- iobservable × 1
- ios × 1
- iot × 1
- ipad × 1
- isomorphic × 1
- javascript optimization × 1
- javascript semanticui resources × 1
- jquery-plugin × 1
- jquery-ui × 1
- jquery-ui-datepicker × 1
- js × 1
- kendo datasource × 1
- kendochart × 1
- kendoui compiler × 1
- knockout × 1
- l10n × 1
- learning × 1
- library × 1
- libs × 1
- license × 1
- licensing × 1
- lineserieszonescfg × 1
- local setting × 1
- localization × 1
- logging × 1
- loop × 1
- macros × 1
- mailboxprocessor × 1
- mapping × 1
- maps × 1
- markerclusterer × 1
- markup × 1
- marshal × 1
- math × 1
- mathjax × 1
- message × 1
- message passing × 1
- message-passing × 1
- meta × 1
- metro style × 1
- micro orm × 1
- minimum-requirements × 1
- mix × 1
- mobile installation × 1
- mod_mono × 1
- modal × 1
- module × 1
- mouseevent × 1
- mouseposition × 1
- multidimensional × 1
- multiline × 1
- multithreading × 1
- mysql × 1
- mysqlclient × 1
- nancy × 1
- native × 1
- nested × 1
- nested loops × 1
- node × 1
- nunit × 1
- object relation mapper × 1
- object-oriented × 1
- om × 1
- onboarding × 1
- onclick × 1
- optimization × 1
- option × 1
- orm × 1
- os x × 1
- output-path × 1
- override × 1
- paper × 1
- parameter × 1
- persistence × 1
- persistent data structure × 1
- phonegap × 1
- pola × 1
- post × 1
- powerpack × 1
- prefix tree × 1
- principle of least authority × 1
- privacy × 1
- private × 1
- profile × 1
- programming × 1
- project × 1
- project euler × 1
- projekt_feladat × 1
- protected × 1
- provider × 1
- proxy × 1
- ptvs × 1
- public × 1
- pure f# × 1
- purescript × 1
- qna × 1
- quant × 1
- query sitelet × 1
- question × 1
- quotations × 1
- range × 1
- raphael × 1
- razor × 1
- rc × 1
- reactjs × 1
- real-time × 1
- ref × 1
- region × 1
- released in 4.0.190.100-rc × 1
- reporting × 1
- responsive design × 1
- rest api × 1
- rest sitelet × 1
- restful × 1
- round table × 1
- router × 1
- routing × 1
- rpc reverseproxy × 1
- runtime × 1
- sales × 1
- sample × 1
- sampleapp × 1
- scriptcs × 1
- scripting × 1
- search × 1
- self hosted × 1
- semanticui × 1
- sequence × 1
- serialisation × 1
- service × 1
- session-state × 1
- sharepoint × 1
- signals × 1
- sitelet website × 1
- sitelet.protect × 1
- sitlets × 1
- slickgrid × 1
- source code × 1
- sqlentityconnection × 1
- ssl × 1
- standards × 1
- static content × 1
- stickynotes × 1
- streamreader × 1
- stress × 1
- strong name × 1
- structures × 1
- submitbutton × 1
- subscribe × 1
- svg example html5 websharper.ui.next × 1
- sweetalert × 1
- system.datetime × 1
- system.reflection.targetinvocationexception × 1
- table storage × 1
- targets × 1
- tdd × 1
- templates ui.next × 1
- templating × 1
- text parsing × 1
- three.js × 1
- time travel × 1
- tls × 1
- tooltip × 1
- tracing × 1
- tsunamiide × 1
- turkish × 1
- twitter-bootstrap × 1
- type erasure × 1
- type inference × 1
- type providers × 1
- type-providers × 1
- typeprovider × 1
- ui next forms × 1
- ui-next × 1
- ui.next jqueryui × 1
- ui.next charting × 1
- ui.next formlets × 1
- ui.next forms × 1
- ui.next suave visualstudio × 1
- ui.next templating × 1
- unicode × 1
- unittest client × 1
- upload × 1
- usersession × 1
- validation × 1
- vb × 1
- vb.net × 1
- vector × 1
- view.map × 1
- visal studio × 1
- visual f# × 1
- visual studio 11 × 1
- visual studio 2012 × 1
- visual studio shell × 1
- vs2017 compiler zafir × 1
- vsix × 1
- web api × 1
- web-scraping × 1
- webapi × 1
- webcomponents × 1
- webforms × 1
- webgl × 1
- webrtc × 1
- webshaper × 1
- websharper async × 1
- websharper codemirror × 1
- websharper f# google × 1
- websharper forms × 1
- websharper reactive × 1
- websharper rpc × 1
- websharper sitelets routing × 1
- websharper warp × 1
- websharper-interface-generator × 1
- websharper.chartsjs × 1
- websharper.com × 1
- websharper.exe × 1
- websharper.owin × 1
- websharper.ui.next × 1
- websharper.ui.next jquery × 1
- websockets iis × 1
- why-websharper × 1
- windows 7 × 1
- windows 8 × 1
- windows-phone × 1
- winrt × 1
- www.grabbitmedia.com × 1
- xamarin × 1
- xml × 1
- yeoman × 1
- yield × 1
- zafir beta × 1
- zafir websharper4 × 1
- zarovizsga × 1
![]() |
Copyright (c) 2011-2012 IntelliFactory. All rights reserved. Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy |
Built with WebSharper |
I define an abstract generic class in C# (a persistent dictionary, here I have removed the actual persistence mechanism for simplicity and replaced it by a Hello() method):
Now I would like to fill out the undefined functionality in F#, like this:
This gives me a curious error message "Method or object constructor 'MyClass`2' not found". What am I doing wrong, and why is the compiler looking for a backquote-number class implementation?