You could always implement this part of your code in C# to get the auto-magic scoping you want and call from F#. Or you could wrap a private event and provide a member fn that only allow subclasses to add observers, as they can't trigger the event if they don't have access to it.
Or just do what some prefer to do anyway - just make the event/delgate/interface public and put an XML comment on it saying that the event is normally triggered internally only and not to call it unless you really mean it, and leave it up to the caller to be mature enough to decide whether they should trigger it or not. (There are dozens of times some API designer has seen fit to make something sealed/final, private, opaque, etc., when if you're writing a testing harness or something else that makes the API a PITA or downright impossible to use without extreme measures like reflection or worse.)
Well I am working on a project now that is just for me so I can obviously make things public if I wanted to, and on occasion I've taken the easy route when I've run into roadblocks with F#. However I'm really trying to force myself to do things in the functional style, sticking with immutability etc.
I've made a lot of progress with F#, but now that I have more of a real world application I'm running into walls like this occasionally. So when I see something that looks like it will be a real shortcoming when developing large scale systems I like to ask around and see if I'm misunderstanding something about the language design choices. In this case I just don't get why protected was poo-pooed.
Another thing I'm kinda struggling with is interfaces and the fact that you have to explicitly cast back to the interface before invoking functions on the object that implements it. While this doesn't expose the same kind of risk that the lack of protected does, it makes the code unwieldy and verbose. I've read several of the arguments about why the explicit cast is better, but remain unconvinced.
Derek
An easy (but verbose) way to circumvent the problem with the interface is to implement a member-function (with the same name or whatever you fell like) and just use this function in the interface-implementation.
I'm not quite sure what you mean here, could you post an example?
Thanks, Derek
I'm not quite sure what you mean here, could you post an example?
Thanks, Derek
Hi,
sorry english is not my first language so maybe I got some issues with making my ideas clear. So what exactly is unclear?
I guess the last rants should be clear to everyone who ever used the F# project-system inside VS. And the stuff with static declarations and constructors inside a interface should be as well.
So I guess it's the first stuff.
Lets say you want to implement some kind of arithmetic interface (lets make it simple and stick to addition for now) - you can do something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
type IAddition<'a> = abstract Add : 'a*'a -> 'a abstract Zero : 'a with get type MyInt(i) = member m.Value = i interface IAddition<MyInt> with member i.Zero = new MyInt(0) member i.Add (a,b) = new MyInt (a.Value + b.Value) module Tests = let x = new MyInt(5) let y = new MyInt(6) let z = (x :> IAddition<_>).Add(x,y)
Isn't that ugly? Without compiler support to nicely translate the Add it's unusable. And even worse - I have to make the interface generic.
What i'd like to see (and use) is something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
type IAddition as A = abstract static Zero : A with get abstract static Inv : A -> A abstract static (+) : A*A -> A default (+) (a,b) = a - (Inv b) abstract static (-) : A*A -> A default (-) (a,b) = a + (Inv b) type MyInt(i) = member m.Value = i interface IAddition with static member Zero = new MyInt(0) static member Inv a = new MyInt (- a.Value) static member (+) (a,b) = new MyInt (a.Value + b.Value)
And languages like Haskel provide something very similiar (and even more powerful) than this - you can even watch some lectures on channel 9 on "Type Classes" and der uses.
I don't know if they ever manage to give us full TC support but even for day-to-day development I'm graving for something easy like this
1 2 3 4
class Foo<tX> where tX : new(int initValue)
I have to disagree.
Making something public only to allow test to be written in s simple way is IMHO against everything encapsulation stands for.
For me the best thing of OO design is that I don't have to comment every possible missuse of some function by just making those not accessible from the outside.
TDD is fine but in most interesting cases (those cases where you have indeed to think to make some code work) it just fails (try writing - lets say a sorting - algorithm with TDD - won't work).
To stumple back to the main question: yeah it's a shame that those simple thinks are somewhat hard in F# and it's mostly those thinks (together with no good refactoring, designer or tool support) that makes me try to do more things in F# but end using C# anyway.
F# is real fun and I love to use it but as we don't seem to get mor FP support in the CLR in the near future and as C# and VB will *lend* the most usefull feature (async) and will even make it better (IMHO) I fear that F# will be less and less a option .... the geek in me cries out indeed (if I don't get any real support I can do my fun and geek stuff in Haskel instead)
Well sorry for getting real OP but I just felt like saying this stuf.
Two different topics...
>Making something public only to allow test to be written
I didn't say that was the only reason - and making something public was only one out of three choices I posted - there are probably more. I just happen to like the Python-esque approach of exposing more, and having conventions such as .thisIsPublic and ._thisIsMorePrivate, etc.
Now, I would <i>much rather <i>have some sort of capability-based architecture with direct support for generic user-defined access levels rather than just the coarse-grained OO-centric access modifiers we have now. That way you could define API levels for Mort, Elivis and Einstein, for Testers, Sandboxed in the browser or not, etc., some of which would require compiler switches or access tokens - but I haven't seen this on the .Net radar. You could do this failry easily at a tooling level (with less safety) with [Attributes] in code that IDE would look at to filter out methods not supported by the current set of filter tokens or access-level. If the OP is writing an API for to be used by thousands of programmers of varying skill then I agree that the public solution is not a good idea -- but if he's writing some classes for himself or for a few programmers, I don't think you really need to spend many cycles on implementing perfect design patterns, but rather solving the problem at hand. > we don't seem to get mor FP support in the CLR Tooling support I agree with 100% (though F# makes this hard than C#), but in what way is the CLR not supporting F# to the degree that you'd wish? [Looks like based on some posting titles you're mostly concerned with immutability?]
> we don't seem to get mor FP support in the CLR
Tooling support I agree with 100% (though F# makes this hard than C#), but in what way is the CLR not supporting F# to the degree that you'd wish? [Looks like based on some posting titles you're mostly concerned with immutability?]
Hi,
well there are a couple of thinks - real checked immutability is a minor think. What I really like to see (for C# too) are type-classes or more powerful interfaces (for example we can't even do a simple think like a arithmetic-interface, because we can't define static members, we can't refer to the type that implements the interface and we certainly can't "Mix"; more: I can say "new" to indicate that I want a constructor but behold it will only be a () -> xyz but what I want is to tell the stupid think what signature the ctor should have (ISerializable is a good example - you have to remember to implement the right ctor because the interface certainly don't indicate it's need).
Then: I don't want to queue the files in the right order. I want cross/mutual referenzes (type ... and ...) across files. I want good subfolder support, etc.
As it is you can use F# to prototype short libs or some little APIs but that's it - I really tried hard but it's a pain to write your buisiness logic or even some heavier helper-Dll in F# so I allways end up using C# with all it's nice support - and I really hate it.
But all we here is some (intersting) new thing with data and F# - that is intersting from a sci. standpoint but just don't make F# for the day-to-day development better.
>> we don't seem to get mor FP support in the CLR
> ...
Ok, so it's not the "CLR" you are addressing, but the F# language design and the tools support.
I agree that type-class are cool, but I'm not sure if they're on the radar or not. An actual active meta-class hierarchy, in which a "static" in a class is really putting a non-static in the meta-class (which would support inher. of c'tors, etc.) would be cool or may be able to address some issues in a more OO-way and would be applicable to all .Net languages.
>so I allways end up using C# with all it's nice support - and I really hate it
Yeah, I sometimes write the "scaffolding" in C# for tooling support, and the "guts" in F# for such cases.
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 |
Hi
I've just become familiar with Events in F# and by and large I like the way that things work especially combined with pipelining and the Observable functions. However there is one problem I'm having with the design of class hierarchies and the triggering of events.
Normally in C# if I have an event defined in a base class it is private, but I create a protected member function that can be used to trigger the event from one of the subclasses. This can't be done in F# since it doesn't provide for Protected members. So I was left with the choice of making the Trigger method public on the base class (which is a bad idea). Or simply not having the event defined in the base class, and instead making separate events in the subclasses.
I decided to go the route of separate events in the subclasses. But this is totally sub-optimal because events defined in the sub-class are naturally only able to provide info about what's going on in the subclass and not what's happening in the parent.
Is there some better way of doing this in F#?
Derek