Comments (20)
You provide an implicit PPrinter[T]
to tell it how to pprint something, and it should do it (modulo bugs). PPrinter[T]
is separate from PPrint[T]
to try and make the contravariant typeclasses work (seems to...)
This is describe too-briefly in http://lihaoyi.github.io/Ammonite/#Ammonite-PPrint. Could definitely use more prose.
from ammonite.
I haven't been able to make it work for long enough to try much out.
@ implicit def implicitPPrint[A](implicit z: Show[A]): PPrint[A] = null
Compilation Failed
Main.scala:69: '}' expected but identifier found.
+:$,
^
@
I guess I'm skeptical that, assuming other things worked, that if I had an implicit Show[String] which always prints "bippy" and I gave the literal String "foo" then I would see res0: bippy
. But that's what I am after.
from ammonite.
(Make the above PPrinter, obviously not going to save the day.)
from ammonite.
Same error as #36, possibly just fixed by @lihaoyi
from ammonite.
I'm running against 47a361e, so guessing not fixed.
from ammonite.
yeah imports are borked and being tracked here #36.
Hopefully after playing whack-a-mole and adding a few more unit tests for all these failing cases it should be in reasonable shape.
from ammonite.
Oh, when you say just you really mean "just".
from ammonite.
A few minutes ago, yeah :-)
from ammonite.
note that not all tests pass yet, but it should put it in a slightly better state. I'll come back and make it better after I'm done writing puppet scripts for $$$ at work
from ammonite.
Update: it's not fixed :-|
from ammonite.
By the way, if you want to improve on the scala repl this is the hard way to do it. Trying to elicit expected behavior wrt implicits and user-given imports in a repl setting via a rat's nest of generated strings is never going to work right. You have to manage the namespace directly.
from ammonite.
@paulp I don't understand. I am managing the namespace directly, and have a Map[String, ImportData]
of where the various things I'm importing come from. Do you think I should dive deeper into the compiler internals and munge the data-structures myself?
from ammonite.
@lihaoyi Yes, that's what I mean. Here are some excerpts from mine.
class Analyzer(val global: outer.type) extends typechecker.Analyzer {
def filteredRootContext(unit: ScalpelUnit, tree: Tree = EmptyTree): Context = rootContext(unit, tree)
override def newNamer(context: Context): ScalpelNamer = new ScalpelNamer(context)
override def newTyper(context: Context): ScalpelTyper = new ScalpelTyper(context)
class ScalpelTyper(context: Context) extends Typer(context) {
override def typed1(tree: Tree, mode: Mode, pt: Type): Tree = {
super.typed1(tree, mode, pt)
}
override def typed(tree: Tree, mode: Mode, pt: Type): Tree = {
strace(s"typed($tree, $mode, $pt)")
tree match {
case Ident(name) =>
strace(s"typed($tree, $mode, $pt)")
bindings get name.swap foreach { fullType =>
val ref = atPos(tree.pos)(fullType.fullNameSelection)
strace(s"Inserting $ref for $name")
return super.typed(ref, mode, pt)
}
case _ =>
}
super.typed(tree, mode, pt)
}
}
override def findMacroClassLoader(): ClassLoader = new AbstractFileClassLoader(outdir, super.findMacroClassLoader)
}
trait Bindings[K, V] {
def prev: Bindings[K, V] // the bindings which preceded these - collisions are shadowed
def defined: Set[K] // keys defined directly in this instance
def imported: Set[K] // keys directly imported by this instance
def apply(key: K): V // if defined or imported in this instance, the value, otherwise consult prev
def keys: Set[K] // directly defined/imported keys plus all keys of prev
def contains(key: K): Boolean // if the key is defined/imported here or in prev
}
trait FullTypes {
val global: Global
import global._, definitions._
private[this] var currentBindings: ReBindings = NoBindings
def isBound(name: nm.Name) = bindings contains name
def lookup(name: nm.Name) = bindings(name)
def bindings = currentBindings
def applyBindings(f: ReBindings => ReBindings) = currentBindings = f(currentBindings)
def retainBindings(p: nm.Name => Boolean): Unit = currentBindings = currentBindings filterKeys p
def addBindings(bs: ReMap): Unit = currentBindings = currentBindings ++ bs
def setBindings(bs: ReBindings): Unit = currentBindings = bs
def importAllFrom(name: String): Unit = wrap(importAllFrom(staticTerm(name)))
def importAllFrom(tpe: FullType): Unit = addBindings(tpe.membersMap)
def bindOne(name: nm.Name, value: FullType): Unit = addBindings(Map(name -> value))
type ReBindings = Bindings[nm.Name, FullType]
type ReMap = Map[nm.Name, FullType]
def NoBindings: ReBindings = Bindings.empty
...
}
from ammonite.
What it all leads to is taking the parse tree and attaching symbols to identifiers directly, based on the bindings you are tracking yourself. Then you hand that tree off to typer to let it go the rest of the way.
from ammonite.
@paulp Seems plausible. I don't know how well it'd actually work in practice: it seems pretty complicated, but stitching strings is starting to get complicated too. Likely I will keep this stuff in mind as I keep playing whack-a-mole with the string splicer, and if the string splicing gets too annoying then I'll try your approach
from ammonite.
This works now
@ class C
defined class C
@ implicit def pprint = ammonite.pprint.PPrinter[C]((t, c) => Iterator("INSTANCE OF CLASS C"))
defined function pprint
@ new C
res2: cmd0.C = INSTANCE OF CLASS C
from ammonite.
Yes, it is pretty complicated, because the compiler is nothing but complicated. You haven't gotten to the real complications in in string land yet. Do you know why the repl creates all those nested objects? Do you intend to duplicate that approach?
from ammonite.
I know why the REPL creates nested objects, and I think I can avoid doing that. The main distinction is that I expand out imports into their individual names and the nsc.interpreter
doesn't. Thus I can avoid relying on the depth
of an import to impose ordering, and can emulate import-shadowing manually by adding and removing imports at the correct time.
It's not 100% accurate yet (e.g. it doesn't distinguish the type namespace from the term namespace) but it's pretty darn close. If you can elaborate on what test cases w.r.t. implicits would fail, we may be able to fix them, or we may decide that some of the semantics are just broken (e.g. Scala's ambiguous-import errors) and document/wontfix them rather than trying to emulate.
from ammonite.
I guarantee you that you underestimate the complexity of reproducing the compiler's rules for ambiguous imports. You will never make it work well this way. I won't need to elaborate because you will discover it for yourself.
from ammonite.
I await my enlightenment then ^_^
from ammonite.
Related Issues (20)
- running tests failed unable to find utest
- not working in Windows, but found a workaround
- upickle.default.macroRW not working in Ammonite Repl 2.5.11 (Scala 3.2.2 Java 17.0.8.1)
- varargs in main causes errors
- unable to access package-private symbols from .sc files HOT 1
- os.proc.pipeTo() is not available HOT 1
- Deprecate `object $` to avoid unsoundess
- Please publish for Scala 2.12.19 and 2.13.13 HOT 1
- Publish for Scala 3.3.2, 3.3.3 & 3.4.0 HOT 2
- scala.reflect.internal.FatalError: bad constant pool index: 0 at pos HOT 4
- Please publish for Scala 2.13.14 HOT 6
- import $ivy ERROR HOT 2
- Scala 3: Importing circe-core breaks further evaluation due to `export` identifier HOT 1
- Installation via bootstrap fails HOT 4
- Error exits Ammonite shell when trying to look up methods for a Map object HOT 1
- no 3.3-3.0.0-M2 release artifact? HOT 1
- Publish artifact for 2.5.x / Scala 2.13.14 HOT 2
- REPL throws `@ error while loading CodeColors` for Scala 3 LTS HOT 10
- Support scala-cli directives
- Ammonite crashes with "scala.MatchError: ArraySeq()" in highlightFrame in Repl.scala
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 ammonite.