New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

infer module kind from its input #621

Open
sgtz opened this Issue Nov 17, 2017 · 6 comments

Comments

Projects
None yet
4 participants
@sgtz

sgtz commented Nov 17, 2017

Brief Module Syntax

I propose we make it easier to compose function chains by inferring the module by examining the data type being operated on.

The existing way of approaching this problem in F# is to use List.map id |> List.map id |> List.map id. Saying List dot "List." each time is repetitive. The same goes for Seq and Array.

Pros and Cons

The advantages of making this adjustment to F# are:
• chaining functions together will become less verbose, so intention will be easier to see.

The disadvantages of making this adjustment to F# are:
• an explicit mandate may be desirable in large code bases, and in large teams... but...
• currently, the parsing/compiling rules are simpler. Simplicity at this level is desirable, too. It's a trade-off.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): M

Related suggestions: (put links to related suggestions here)

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • [ X ] This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • [ X ] I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • [ X ] This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • [ X ] This is not a breaking change to the F# language design
  • [ X ] I or my company would be willing to help implement and/or test this
@rmunn

This comment has been minimized.

Show comment
Hide comment
@rmunn

rmunn Nov 17, 2017

Although this is not exactly a duplicate of #243 (adding typeclasses to the language), if #243 is implemented then this suggestion may become redundant. Typeclasses would allow something like:

class Mappable =
    abstract map : ( 'a -> 'b ) -> 'm<'a> -> 'm<'b>

type Seq with
class Mappable with
    member map = Seq.map

type Option with
class Mappable with
    member map = Option.map

Then it would be possible to just write a single map function that can handle any Mappable type:

let map (f : 'a -> 'b) (collection : Mappable) = collection.map f

The syntax would, of course, depend on how #243 would eventually be implemented.

rmunn commented Nov 17, 2017

Although this is not exactly a duplicate of #243 (adding typeclasses to the language), if #243 is implemented then this suggestion may become redundant. Typeclasses would allow something like:

class Mappable =
    abstract map : ( 'a -> 'b ) -> 'm<'a> -> 'm<'b>

type Seq with
class Mappable with
    member map = Seq.map

type Option with
class Mappable with
    member map = Option.map

Then it would be possible to just write a single map function that can handle any Mappable type:

let map (f : 'a -> 'b) (collection : Mappable) = collection.map f

The syntax would, of course, depend on how #243 would eventually be implemented.

@sgtz

This comment has been minimized.

Show comment
Hide comment
@sgtz

sgtz Nov 17, 2017

@rmunn: thanks for the class link. Nice feature. Not quite the same thing though. We could take context further than this in a sensible default direction, perhaps. I wonder if this suggestion could supplement this direction (that link is a very long thread... I skimmed some of the discussion so not completely groked as of this writing).

sgtz commented Nov 17, 2017

@rmunn: thanks for the class link. Nice feature. Not quite the same thing though. We could take context further than this in a sensible default direction, perhaps. I wonder if this suggestion could supplement this direction (that link is a very long thread... I skimmed some of the discussion so not completely groked as of this writing).

@xuanduc987

This comment has been minimized.

Show comment
Hide comment
@xuanduc987

xuanduc987 Nov 17, 2017

@sgtz without #243 how can compiler infer this code?

let someFunc x =
  x
  |> map (+) 1
  |> sum

compare with

let someFunc x =
  x
  |> List.map (+) 1
  |> List.sum

The compiler could infer that someFunc is int list -> int

xuanduc987 commented Nov 17, 2017

@sgtz without #243 how can compiler infer this code?

let someFunc x =
  x
  |> map (+) 1
  |> sum

compare with

let someFunc x =
  x
  |> List.map (+) 1
  |> List.sum

The compiler could infer that someFunc is int list -> int

@sgtz

This comment has been minimized.

Show comment
Hide comment
@sgtz

sgtz Nov 17, 2017

@xuanduc987: I propose that code block A would fail unless it had (x : 'x list) or a call (infer chain) to someFunc such that the shape of 'x was known at some later stage. Also, the 'x shape (in this case a list) could be defined by the data.

sgtz commented Nov 17, 2017

@xuanduc987: I propose that code block A would fail unless it had (x : 'x list) or a call (infer chain) to someFunc such that the shape of 'x was known at some later stage. Also, the 'x shape (in this case a list) could be defined by the data.

@piaste

This comment has been minimized.

Show comment
Hide comment
@piaste

piaste Nov 19, 2017

As I understand it, the List<'t> type and the List module currently have nothing to do with each other, except that they kind of happen to share a name (minus the type parameter). Ditto for Array, Seq, et cetera. From the compiler's point of view, the fact that they contain functions which operate on certain types is pure coincidence.

For this sort of inference to work, the compiler would need to be made aware that the List module is semantically connected to the type. Should the rule be simple name matching (including the namespace, I suppose)? Or should the connection be explicit, such as with an attribute?

piaste commented Nov 19, 2017

As I understand it, the List<'t> type and the List module currently have nothing to do with each other, except that they kind of happen to share a name (minus the type parameter). Ditto for Array, Seq, et cetera. From the compiler's point of view, the fact that they contain functions which operate on certain types is pure coincidence.

For this sort of inference to work, the compiler would need to be made aware that the List module is semantically connected to the type. Should the rule be simple name matching (including the namespace, I suppose)? Or should the connection be explicit, such as with an attribute?

@sgtz

This comment has been minimized.

Show comment
Hide comment
@sgtz

sgtz Nov 19, 2017

sgtz commented Nov 19, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment