Comments (4)
This looks like its because of the desugaring - i.e
(foo = _.length) : (foo: String => Int)
becomes
NamedTuple.withNames(Tuple1(_.length))[Tuple1["foo"]] : (foo: String => Int)
// ^^^^^^^^
// nested lambda with no expected type
it might be worth reconsidering this desugaring, or perhaps tunnelling through any expected type to the argument of withNames
.
A tentative plan - perhaps we can add a type ascription to some "watcher" type, that then is resolved on the outside -
(NamedTuple.withNames(Tuple1(_.length): <watch[target]>)[Tuple1["foo"]] : <target>) : (foo: String => Int)
from scala3.
Named tuples are constructed with NamedTuple.withNames
:
extension [V <: Tuple](x: V)
inline def withNames[N <: Tuple]: NamedTuple[N, V] = x
So the call looks like
NamedTuple.withNames[V](tuple)[N]
It's important to have two type parameter lists because the V
is usually inferred but the N
needs to be given explicitly. But they don't nesessarily need to come in that order. One could also imagine to build named tuples using a function like this
def build[N <: Tuple]()[V <: Tuple](x: V): NamedTuple[N, V]
Maybe that would fix the problem. I think it might be worth trying out, but I don't have the bandwidth to do it myself right now.
from scala3.
This solution seems to work without needing clause interleaving, and leaves no trace after inlining:
object NamedTupleBuilder {
opaque type Builder[N <: Tuple] = Unit
def apply[N <: Tuple]: Builder[N] = ()
}
extension [N <: Tuple](inline b: NamedTupleBuilder.Builder[N])
transparent inline def build[V <: Tuple](inline v: V): NamedTuple[N, V] = v.withNames[N]
then we can have the example here:
val m: (foo: String => Int, bar: String => Int) =
(foo = _.length, bar = _.length)
desugar to
val m: (foo: String => Int, bar: String => Int) =
NamedTupleBuilder.apply[("foo", "bar")].build((_.length, _.length))
and it infers perfectly.
here is the tree after typer:
scala> val m: (foo: String => Int, bar: String => Int) = NamedTupleBuilder.apply[("foo", "bar")].build((_.length, _.length))
[[syntax trees at end of typer]] // rs$line$5
package <empty> {
final lazy module val rs$line$5: rs$line$5 = new rs$line$5()
final module class rs$line$5() extends Object() { this: rs$line$5.type =>
val m: (foo : String => Int, bar : String => Int) =
NamedTuple.withNames[(String => Int, String => Int)](
Tuple2.apply[String => Int, String => Int](
{
def $anonfun(_$1: String): Int = _$1.length()
closure($anonfun)
},
{
def $anonfun(_$2: String): Int = _$2.length()
closure($anonfun)
}
)
)[(("foo" : String), ("bar" : String))]
}
}
val m: (foo : String => Int, bar : String => Int) = (rs$line$5$$$Lambda$2022/0x000000012d6005d8@5e08ed28,rs$line$5$$$Lambda$2023/0x000000012d6009a8@24b05292)
from scala3.
I have implemented a fix in #20497 - which also includes a variant of https://github.com/bishabosha/ops-mirror that makes use of named tuples to implement server logic
from scala3.
Related Issues (20)
- Fails to compile java code with a valid java annotation syntax. HOT 2
- Regression in `virtuslab/scala-cli` for derivation HOT 5
- (minor) usage of `scala.ContextFunction0` should produce "context function types require at least one parameter" error
- First ident in Java type name must be type or package
- Inline methods of opaque types leave redundant proxies in byte code
- Wrong unimplemented members reported
- Multi-Source Extension Overloads would be shadowed by local extensions with the same name HOT 4
- Name clash with Ordering HOT 2
- SIP-47 Clause Interleaving + Java = `bad class file` error HOT 1
- Polymorphic capture functions can be exploited to hide captures HOT 1
- Scala 3 generated @main function is generated in package scope HOT 8
- 3.5.0-RC7 Release procedure HOT 1
- "method apply must be called with () argument" must be generated for scala.Function0 HOT 5
- Regression in `softwaremill/tapir` - StaleSymbolException when compiling macros
- type variable resolution contradicts language spec in a case of an inner class extending an outer class HOT 3
- static final null character crashes parser HOT 1
- quoted Symbol.spliceOwner should not be the current class in extends clauses
- Unexpected type representation reached the compiler backend HOT 1
- a type defined in a trait is "not found" in an object that extends the trait (under certain circumstances) HOT 1
- Anonymous givens for two different types with same name create "Duplicate definition" HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from scala3.