diff --git a/.gitignore b/.gitignore index d0c9d9e..f63a763 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,8 @@ *~ # Typescript # emitted code -obj +build/* +!build/package.json # ---> Node # Logs diff --git a/README.md b/README.md index d15fcc4..49e5266 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,6 @@ A final (?) prototype for a refactor of mathjs, culminating the picomath, pocoma To build and run the prototype, run: ``` -npx tsc -node obj +pnpm install +pnpm build-and-run ``` diff --git a/build/package.json b/build/package.json new file mode 100644 index 0000000..3dbc1ca --- /dev/null +++ b/build/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/package.json5 b/package.json5 index 874d5e3..1632098 100644 --- a/package.json5 +++ b/package.json5 @@ -4,6 +4,7 @@ description: 'A hopeful final typescipt-pragmatic mathjs proof-of-concept', main: 'index.ts', scripts: { + 'build-and-run': 'ttsc -b && node build', test: 'echo "Error: no test specified" && exit 1', }, keywords: [ @@ -17,7 +18,15 @@ type: 'git', url: 'https://code.studioinfinity.org/glen/typocomath.git', }, + dependencies: { + 'reflect-metadata': '0.1.13', + 'typescript-rtti': '0.8.2', + }, devDependencies: { - typescript: '^4.9.3', + '@types/node': '18.11.18', + 'ts-node': '10.9.1', + ttypescript: '1.5.15', + typescript: '4.8.4', + 'typescript-rtti': '0.8.2', }, } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 095704b..153c7e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,15 +1,199 @@ lockfileVersion: 5.4 specifiers: - typescript: ^4.9.3 + '@types/node': 18.11.18 + reflect-metadata: 0.1.13 + ts-node: 10.9.1 + ttypescript: 1.5.15 + typescript: 4.8.4 + typescript-rtti: 0.8.2 + +dependencies: + reflect-metadata: 0.1.13 + typescript-rtti: 0.8.2_tjkpoysld524rvy7hjviaz6rje devDependencies: - typescript: 4.9.3 + '@types/node': 18.11.18 + ts-node: 10.9.1_vqcafhj4xvr2nzknlrdklk55zm + ttypescript: 1.5.15_mwhvu7sfp6vq5ryuwb6hlbjfka + typescript: 4.8.4 packages: - /typescript/4.9.3: - resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} - engines: {node: '>=4.2.0'} + /@cspotcode/source-map-support/0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + + /@jridgewell/resolve-uri/3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec/1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true + + /@jridgewell/trace-mapping/0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@tsconfig/node10/1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true + + /@tsconfig/node12/1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14/1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16/1.0.3: + resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} + dev: true + + /@types/node/18.11.18: + resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} + dev: true + + /acorn-walk/8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn/8.8.2: + resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} + engines: {node: '>=0.4.0'} hasBin: true dev: true + + /arg/4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + + /create-require/1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + + /diff/4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /is-core-module/2.11.0: + resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + dependencies: + has: 1.0.3 + dev: true + + /make-error/1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /reflect-metadata/0.1.13: + resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} + dev: false + + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.11.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /ts-node/10.9.1_vqcafhj4xvr2nzknlrdklk55zm: + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.3 + '@types/node': 18.11.18 + acorn: 8.8.2 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.8.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + + /ttypescript/1.5.15_mwhvu7sfp6vq5ryuwb6hlbjfka: + resolution: {integrity: sha512-48ykDNHzFnPMnv4hYX1P8Q84TvCZyL1QlFxeuxsuZ48X2+ameBgPenvmCkHJtoOSxpoWTWi8NcgNrRnVDOmfSg==} + hasBin: true + peerDependencies: + ts-node: '>=8.0.2' + typescript: '>=3.2.2' + dependencies: + resolve: 1.22.1 + ts-node: 10.9.1_vqcafhj4xvr2nzknlrdklk55zm + typescript: 4.8.4 + dev: true + + /typescript-rtti/0.8.2_tjkpoysld524rvy7hjviaz6rje: + resolution: {integrity: sha512-MZUHMX+Up1+7dYaAcOYSTxKc4PNLNXhuXYBkIzEKvQvxJ6xp7wcjTtiIYmB9+RJxRH5/9phZLqKTMpy20aQ4Aw==} + engines: {node: '>=10'} + peerDependencies: + reflect-metadata: ^0.1.13 + typescript: '4.6' + dependencies: + reflect-metadata: 0.1.13 + typescript: 4.8.4 + dev: false + + /typescript/4.8.4: + resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==} + engines: {node: '>=4.2.0'} + hasBin: true + + /v8-compile-cache-lib/3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + + /yn/3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true diff --git a/src/core/Dispatcher.ts b/src/core/Dispatcher.ts index def1bd3..1da89ff 100644 --- a/src/core/Dispatcher.ts +++ b/src/core/Dispatcher.ts @@ -1,3 +1,6 @@ +import "reflect-metadata" +import { reflect, type CallSite } from 'typescript-rtti' + /* A Dispatcher is a collection of operations that do run-time * dispatch on the types of their arguments. Thus, every individual * method is like a typed-function (from the library by that name), @@ -46,6 +49,10 @@ export class Dispatcher { // that's really possible, though. ) { console.log('Pretending to install', name, signature, '=>', returns) + + // @ts-ignore + console.log(name, 'signature', reflect(signature)) + console.log(name, 'dependencies', reflect(dependencies)) //TODO: implement me } installType(name: TypeName, typespec: TypeSpecification) { diff --git a/src/index.ts b/src/index.ts index 297b271..5d8c0e7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,57 @@ import {Dispatcher} from './core/Dispatcher.js' import * as Specifications from './all.js' - -export default new Dispatcher(Specifications) - import {Complex} from './Complex/type.js' import {absquare as absquare_complex} from './Complex/arithmetic.js' +import 'reflect-metadata' +import { ReflectedFunctionParameter, ReflectedObjectRef, reflect } from 'typescript-rtti' +import { square } from './generic/arithmetic.js' + +// verify that typescript-rtti works (just as experiment) +const add = (a: number, b: number): number => a + b +console.log('reflect add') +console.log('parameterNames', reflect(add).parameterNames) +console.log('parameterTypes', reflect(add).parameterTypes.map(type => type.toString())) +console.log('returnType', reflect(add).returnType.toString()) +console.log() +// output: +// reflect function add +// parameterNames [ 'a', 'b' ] +// parameterTypes [ 'class Number', 'class Number' ] +// returnType class Number + +// try out a very simple case (just as experiment) +function createSquare(deps: { + multiply: (a: number, b: number) => number, + subtract: (a: number, b: number) => number +}) { + return (a: number) => deps.multiply(a, a) +} +console.log('reflect createSquare') +console.log('parameter names', reflect(createSquare).parameters.map(parameter => parameter.name)) +console.log('parameter[0]', (reflect(createSquare).parameters[0] as ReflectedFunctionParameter)) +// @ts-ignore +console.log('parameterTypes[0]', (reflect(createSquare).parameterTypes[0] as ReflectedObjectRef)._ref.m) +console.log('parameterTypes[0][0]', + // @ts-ignore + (reflect(createSquare).parameterTypes[0] as ReflectedObjectRef)._ref.m[0].n, + // @ts-ignore + (reflect(createSquare).parameterTypes[0] as ReflectedObjectRef)._ref.m[0] +) +// @ts-ignore +console.log('parameters[0]', reflect(createSquare).parameters[0]) +// FIXME: where to find the information of the types of the dependencies multiply and subtract? + + + +// FIXME: get all types out of Specifications +// console.log('Specifications', reflect(Specifications)) // Throws errors + + +// TODO: import all specificiations (turned off for debugging purposes) +// export default new Dispatcher(Specifications) + + const mockRealAdd = (a: number, b: number) => a+b const mockComplexAbsquare = (z: Complex) => z.re*z.re + z.im*z.im diff --git a/src/numbers/arithmetic.ts b/src/numbers/arithmetic.ts index 11da5c2..ef0af93 100644 --- a/src/numbers/arithmetic.ts +++ b/src/numbers/arithmetic.ts @@ -10,7 +10,7 @@ export const absquare: Signature<'absquare', number> = a => a * a export const reciprocal: Signature<'reciprocal', number> = a => 1 / a export const divide: Signature<'divide', number> = (a, b) => a / b -const basicSqrt = a => isNaN(a) ? NaN : Math.sqrt(a) +const basicSqrt = (a: number) => isNaN(a) ? NaN : Math.sqrt(a) export const conservativeSqrt: Signature<'conservativeSqrt', number> = basicSqrt export const sqrt = diff --git a/tsconfig.json b/tsconfig.json index aae3a94..4470b45 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,15 @@ "compilerOptions": { "target": "ES2022", "rootDir": "./src", - "outDir": "./obj" + "outDir": "./build", + "esModuleInterop": true, + "allowJs": false, + "noImplicitAny": false, + "moduleResolution": "Node", + "plugins": [ + { + "transform": "typescript-rtti/dist/transformer" + } + ] } }