| Book of Mormon |
Annotations |
|
Chapter 5
|
Some have criticized the fact that this olive tree
allegory takes place in a vineyard. That might seem a little questionable,
but my understanding is that olive trees are commonly grown in vineyards
(correct me if I’m wrong on this) at least in some regions. At worst, I think
the fact that the setting is in a vineyard may be an unnecessary detail that
can distract from the rest of the allegory.
|
|
1 Behold, my brethren, do ye not remember to have read the
words of the prophet Zenos, which he spake unto the house of Israel, saying:
|
|
|
2 Hearken, O ye house of Israel, and hear the words of me,
a prophet of the Lord.
|
|
|
3 For behold, thus saith the Lord, I will liken thee, O
house of Israel, like unto a tame olive tree, which a man took and nourished
in his vineyard; and it grew, and waxed old, and began to decay.
|
Allegories use symbolism in story form to teach an
underlying moral or theme. This allegory presents some problems in Book of
Mormon context though.
First of all, the Nephites don’t have any olive trees, so
this aspect of the story would fall pretty flat for such an audience.
Secondly this story is extremely verbose (see Jacob 4:1 for how difficult it
was to engrave the plates, but this long allegory somehow merits the effort?).
The story is confusing, has the Lord of the vineyard taking direction from
the workers, and requires Jacob to explain some of it in the next chapter.
If I had to engrave the principles taught here on metal plates, I think I’d
write something like:
- The House of Israel will be scattered because of its wickedness. (And, as may be inferred symbolically from the story, scattering or hardship can actually lead to growth.)
- Gentiles will be adopted into the covenant and do good works.
- Eventually many of the gentiles will start being evil and be cast off.
- The scattered remnant of Israel will be gathered back, repent, and do good works.
- In the end, the good will be rewarded by the Lord through His work (His atonement), the bad will receive endless damnation (which is not the same as damnation with no end—it is damnation of the Lord—see D&C 19:6-12).
In 2 Ne 31:3 Nephi says, “My soul delighteth in plainness;
for after this manner doth the Lord God work among the children of men.” How
does this allegory fit with that assertion?
|
|
4 And it came to pass that the master of the
vineyard went forth, and he saw that his olive tree began to decay; and he
said: I will prune it, and dig about it, and nourish it, that perhaps it may
shoot forth young and tender branches, and it perish not.
|
“And it came to pass that” is used 31 times in this single
chapter.
|
|
5 And it came to pass that he pruned it, and digged about
it, and nourished it according to his word.
|
|
|
6 And it came to pass that after many days it began to put
forth somewhat a little, young and tender branches; but behold, the main top
thereof began to perish.
|
|
|
7 And it came to pass that the master of the vineyard saw
it, and he said unto his servant: It grieveth me that I should lose this
tree; wherefore, go and pluck the branches from a wild olive tree, and bring
them hither unto me; and we will pluck off those main branches which are
beginning to wither away, and we will cast them into the fire that they may
be burned.
|
|
|
8 And behold, saith the Lord of the vineyard, I take away
many of these young and tender branches, and I will graft them whithersoever
I will; and it mattereth not that if it so be that the root of this tree will
perish, I may preserve the fruit thereof unto myself; wherefore, I will take
these young and tender branches, and I will graft them whithersoever I will.
|
|
|
9 Take thou the branches of the wild olive tree, and graft
them in, in the stead thereof; and these which I have plucked off I will cast
into the fire and burn them, that they may not cumber the ground of my
vineyard.
|
|
|
10 And it came to pass that the servant of the Lord of the
vineyard did according to the word of the Lord of the vineyard, and grafted
in the branches of the wild olive tree.
|
|
|
11 And the Lord of the vineyard caused that it should be
digged about, and pruned, and nourished, saying unto his servant: It grieveth
me that I should lose this tree; wherefore, that perhaps I might preserve the
roots thereof that they perish not, that I might preserve them unto myself, I
have done this thing.
|
|
|
12 Wherefore, go thy way; watch the tree, and nourish it,
according to my words.
|
|
|
13 And these will I place in the nethermost part of my
vineyard, whithersoever I will, it mattereth not unto thee; and I do it that
I may preserve unto myself the natural branches of the tree; and also, that I
may lay up fruit thereof against the season, unto myself; for it grieveth me
that I should lose this tree and the fruit thereof.
|
|
|
14 And it came to pass that the Lord of the vineyard went
his way, and hid the natural branches of the tame olive tree in the
nethermost parts of the vineyard, some in one and some in another, according
to his will and pleasure.
|
|
|
15 And it came to pass that a long time passed away, and
the Lord of the vineyard said unto his servant: Come, let us go down into the
vineyard, that we may labor in the vineyard.
|
|
|
16 And it came to pass that the Lord of the vineyard, and
also the servant, went down into the vineyard to labor. And it came to pass
that the servant said unto his master: Behold, look here; behold the tree.
|
|
|
17 And it came to pass that the Lord of the vineyard
looked and beheld the tree in the which the wild olive branches had been
grafted; and it had sprung forth and begun to bear fruit. And he beheld that
it was good; and the fruit thereof was like unto the natural fruit.
|
|
|
18 And he said unto the servant: Behold, the branches of
the wild tree have taken hold of the moisture of the root thereof, that the
root thereof hath brought forth much strength; and because of the much
strength of the root thereof the wild branches have brought forth tame fruit.
Now, if we had not grafted in these branches, the tree thereof would have
perished. And now, behold, I shall lay up much fruit, which the tree thereof
hath brought forth; and the fruit thereof I shall lay up against the season,
unto mine own self.
|
|
|
19 And it came to pass that the Lord of the vineyard said
unto the servant: Come, let us go to the nethermost part of the vineyard, and
behold if the natural branches of the tree have not brought forth much fruit
also, that I may lay up of the fruit thereof against the season, unto mine
own self.
|
|
|
20 And it came to pass that they went forth whither the
master had hid the natural branches of the tree, and he said unto the servant:
Behold these; and he beheld the first that it had brought forth much fruit;
and he beheld also that it was good. And he said unto the servant: Take of
the fruit thereof, and lay it up against the season, that I may preserve it
unto mine own self; for behold, said he, this long time have I nourished it,
and it hath brought forth much fruit.
|
|
|
21 And it came to pass that the servant said unto his
master: How comest thou hither to plant this tree, or this branch of the
tree? For behold, it was the poorest spot in all the land of thy vineyard.
|
|
|
22 And the Lord of the vineyard said unto him: Counsel me
not; I knew that it was a poor spot of ground; wherefore, I said unto thee, I
have nourished it this long time, and thou beholdest that it hath brought forth
much fruit.
|
|
|
23 And it came to pass that the Lord of the vineyard said
unto his servant: Look hither; behold I have planted another branch of the
tree also; and thou knowest that this spot of ground was poorer than the
first. But, behold the tree. I have nourished it this long time, and it hath
brought forth much fruit; therefore, gather it, and lay it up against the
season, that I may preserve it unto mine own self.
|
|
|
24 And it came to pass that the Lord of the vineyard said
again unto his servant: Look hither, and behold another branch also, which I
have planted; behold that I have nourished it also, and it hath brought forth
fruit.
|
|
|
25 And he said unto the servant: Look hither and behold
the last. Behold, this have I planted in a good spot of ground; and I have
nourished it this long time, and only a part of the tree hath brought forth
tame fruit, and the other part of the tree hath brought forth wild fruit;
behold, I have nourished this tree like unto the others.
|
|
|
26 And it came to pass that the Lord of the vineyard said
unto the servant: Pluck off the branches that have not brought forth good
fruit, and cast them into the fire.
|
|
|
27 But behold, the servant said unto him: Let us prune it,
and dig about it, and nourish it a little longer, that perhaps it may bring
forth good fruit unto thee, that thou canst lay it up against the season.
|
|
|
28 And it came to pass that the Lord of the vineyard and
the servant of the Lord of the vineyard did nourish all the fruit of the
vineyard.
|
|
|
29 And it came to pass that a long time had passed away,
and the Lord of the vineyard said unto his servant: Come, let us go down into
the vineyard, that we may labor again in the vineyard. For behold, the time
draweth near, and the end soon cometh; wherefore, I must lay up fruit against
the season, unto mine own self.
|
|
|
30 And it came to pass that the Lord of the vineyard and
the servant went down into the vineyard; and they came to the tree whose
natural branches had been broken off, and the wild branches had been grafted
in; and behold all sorts of fruit did cumber the tree.
|
|
|
31 And it came to pass that the Lord of the vineyard did
taste of the fruit, every sort according to its number. And the Lord of the
vineyard said: Behold, this long time have we nourished this tree, and I have
laid up unto myself against the season much fruit.
|
|
|
32 But behold, this time it hath brought forth much fruit,
and there is none of it which is good. And behold, there are all kinds of bad
fruit; and it profiteth me nothing, notwithstanding all our labor; and now it
grieveth me that I should lose this tree.
|
|
|
33 And the Lord of the vineyard said unto the servant:
What shall we do unto the tree, that I may preserve again good fruit thereof
unto mine own self?
|
|
|
34 And the servant said unto his master: Behold, because
thou didst graft in the branches of the wild olive tree they have nourished
the roots, that they are alive and they have not perished; wherefore thou
beholdest that they are yet good.
|
|
|
35 And it came to pass that the Lord of the vineyard said
unto his servant: The tree profiteth me nothing, and the roots thereof profit
me nothing so long as it shall bring forth evil fruit.
|
|
|
36 Nevertheless, I know that the roots are good, and for
mine own purpose I have preserved them; and because of their much strength
they have hitherto brought forth, from the wild branches, good fruit.
|
|
|
37 But behold, the wild branches have grown and have
overrun the roots thereof; and because that the wild branches have overcome
the roots thereof it hath brought forth much evil fruit; and because that it
hath brought forth so much evil fruit thou beholdest that it beginneth to
perish; and it will soon become ripened, that it may be cast into the fire,
except we should do something for it to preserve it.
|
|
|
38 And it came to pass that the Lord of the vineyard said
unto his servant: Let us go down into the nethermost parts of the vineyard,
and behold if the natural branches have also brought forth evil fruit.
|
|
|
39 And it came to pass that they went down into the
nethermost parts of the vineyard. And it came to pass that they beheld that
the fruit of the natural branches had become corrupt also; yea, the first and
the second and also the last; and they had all become corrupt.
|
|
|
40 And the wild fruit of the last had overcome that part
of the tree which brought forth good fruit, even that the branch had withered
away and died.
|
|
|
41 And it came to pass that the Lord of the vineyard wept,
and said unto the servant: What could I have done more for my vineyard?
|
|
|
42 Behold, I knew that all the fruit of the vineyard, save
it were these, had become corrupted. And now these which have once brought
forth good fruit have also become corrupted; and now all the trees of my
vineyard are good for nothing save it be to be hewn down and cast into the
fire.
|
|
|
43 And behold this last, whose branch hath withered away,
I did plant in a good spot of ground; yea, even that which was choice unto me
above all other parts of the land of my vineyard.
|
|
|
44 And thou beheldest that I also cut down that which
cumbered this spot of ground, that I might plant this tree in the stead
thereof.
|
|
|
45 And thou beheldest that a part thereof brought forth
good fruit, and a part thereof brought forth wild fruit; and because I
plucked not the branches thereof and cast them into the fire, behold, they
have overcome the good branch that it hath withered away.
|
|
|
46 And now, behold, notwithstanding all the care which we
have taken of my vineyard, the trees thereof have become corrupted, that they
bring forth no good fruit; and these I had hoped to preserve, to have laid up
fruit thereof against the season, unto mine own self. But, behold, they have
become like unto the wild olive tree, and they are of no worth but to be hewn
down and cast into the fire; and it grieveth me that I should lose them.
|
|
|
47 But what could I have done more in my vineyard? Have I
slackened mine hand, that I have not nourished it? Nay, I have nourished it,
and I have digged about it, and I have pruned it, and I have dunged it; and I
have stretched forth mine hand almost all the day long, and the end draweth
nigh. And it grieveth me that I should hew down all the trees of my vineyard,
and cast them into the fire that they should be burned. Who is it that has
corrupted my vineyard?
|
|
|
48 And it came to pass that the servant said unto his
master: Is it not the loftiness of thy vineyard—have not the branches thereof
overcome the roots which are good? And because the branches have overcome the
roots thereof, behold they grew faster than the strength of the roots, taking
strength unto themselves. Behold, I say, is not this the cause that the trees
of thy vineyard have become corrupted?
|
|
|
49 And it came to pass that the Lord of the vineyard said
unto the servant: Let us go to and hew down the trees of the vineyard and
cast them into the fire, that they shall not cumber the ground of my
vineyard, for I have done all. What could I have done more for my vineyard?
|
|
|
50 But, behold, the servant said unto the Lord of the
vineyard: Spare it a little longer.
|
|
|
51 And the Lord said: Yea, I will spare it a little
longer, for it grieveth me that I should lose the trees of my vineyard.
|
|
|
52 Wherefore, let us take of the branches of these which I
have planted in the nethermost parts of my vineyard, and let us graft them
into the tree from whence they came; and let us pluck from the tree those
branches whose fruit is most bitter, and graft in the natural branches of the
tree in the stead thereof.
|
|
|
53 And this will I do that the tree may not perish, that,
perhaps, I may preserve unto myself the roots thereof for mine own purpose.
|
|
|
54 And, behold, the roots of the natural branches of the
tree which I planted whithersoever I would are yet alive; wherefore, that I
may preserve them also for mine own purpose, I will take of the branches of
this tree, and I will graft them in unto them. Yea, I will graft in unto them
the branches of their mother tree, that I may preserve the roots also unto
mine own self, that when they shall be sufficiently strong perhaps they may
bring forth good fruit unto me, and I may yet have glory in the fruit of my
vineyard.
|
|
|
55 And it came to pass that they took from the natural
tree which had become wild, and grafted in unto the natural trees, which also
had become wild.
|
|
|
56 And they also took of the natural trees which had
become wild, and grafted into their mother tree.
|
|
|
57 And the Lord of the vineyard said unto the servant:
Pluck not the wild branches from the trees, save it be those which are most
bitter; and in them ye shall graft according to that which I have said.
|
|
|
58 And we will nourish again the trees of the vineyard,
and we will trim up the branches thereof; and we will pluck from the trees
those branches which are ripened, that must perish, and cast them into the
fire.
|
|
|
59 And this I do that, perhaps, the roots thereof may take
strength because of their goodness; and because of the change of the
branches, that the good may overcome the evil.
|
|
|
60 And because that I have preserved the natural branches
and the roots thereof, and that I have grafted in the natural branches again
into their mother tree, and have preserved the roots of their mother tree,
that, perhaps, the trees of my vineyard may bring forth again good fruit; and
that I may have joy again in the fruit of my vineyard, and, perhaps, that I
may rejoice exceedingly that I have preserved the roots and the branches of
the first fruit—
|
|
|
61 Wherefore, go to, and call servants, that we may labor
diligently with our might in the vineyard, that we may prepare the way, that
I may bring forth again the natural fruit, which natural fruit is good and
the most precious above all other fruit.
|
|
|
62 Wherefore, let us go to and labor with our might this
last time, for behold the end draweth nigh, and this is for the last time
that I shall prune my vineyard.
|
|
|
63 Graft in the branches; begin at the last that they may
be first, and that the first may be last, and dig about the trees, both old
and young, the first and the last; and the last and the first, that all may
be nourished once again for the last time.
|
|
|
64 Wherefore, dig about them, and prune them, and dung
them once more, for the last time, for the end draweth nigh. And if it be so
that these last grafts shall grow, and bring forth the natural fruit, then
shall ye prepare the way for them, that they may grow.
|
|
|
65 And as they begin to grow ye shall clear away the
branches which bring forth bitter fruit, according to the strength of the
good and the size thereof; and ye shall not clear away the bad thereof all at
once, lest the roots thereof should be too strong for the graft, and the
graft thereof shall perish, and I lose the trees of my vineyard.
|
|
|
66 For it grieveth me that I should lose the trees of my
vineyard; wherefore ye shall clear away the bad according as the good shall
grow, that the root and the top may be equal in strength, until the good
shall overcome the bad, and the bad be hewn down and cast into the fire, that
they cumber not the ground of my vineyard; and thus will I sweep away the bad
out of my vineyard.
|
|
|
67 And the branches of the natural tree will I graft in
again into the natural tree;
|
|
|
68 And the branches of the natural tree will I graft into
the natural branches of the tree; and thus will I bring them together again,
that they shall bring forth the natural fruit, and they shall be one.
|
|
|
69 And the bad shall be cast away, yea, even out of all
the land of my vineyard; for behold, only this once will I prune my vineyard.
|
|
|
70 And it came to pass that the Lord of the vineyard sent
his servant; and the servant went and did as the Lord had commanded him, and
brought other servants; and they were few.
|
|
|
71 And the Lord of the vineyard said unto them: Go to, and
labor in the vineyard, with your might. For behold, this is the last time
that I shall nourish my vineyard; for the end is nigh at hand, and the season
speedily cometh; and if ye labor with your might with me ye shall have joy in
the fruit which I shall lay up unto myself against the time which will soon
come.
|
|
|
72 And it came to pass that the servants did go and labor
with their mights; and the Lord of the vineyard labored also with them; and
they did obey the commandments of the Lord of the vineyard in all things.
|
|
|
73 And there began to be the natural fruit again in the
vineyard; and the natural branches began to grow and thrive exceedingly; and
the wild branches began to be plucked off and to be cast away; and they did
keep the root and the top thereof equal, according to the strength thereof.
|
|
|
74 And thus they labored, with all diligence, according to
the commandments of the Lord of the vineyard, even until the bad had been
cast away out of the vineyard, and the Lord had preserved unto himself that
the trees had become again the natural fruit; and they became like unto one
body; and the fruits were equal; and the Lord of the vineyard had preserved
unto himself the natural fruit, which was most precious unto him from the
beginning.
|
|
|
75 And it came to pass that when the Lord of the vineyard
saw that his fruit was good, and that his vineyard was no more corrupt, he
called up his servants, and said unto them: Behold, for this last time have
we nourished my vineyard; and thou beholdest that I have done according to my
will; and I have preserved the natural fruit, that it is good, even like as
it was in the beginning. And blessed art thou; for because ye have been
diligent in laboring with me in my vineyard, and have kept my commandments,
and have brought unto me again the natural fruit, that my vineyard is no more
corrupted, and the bad is cast away, behold ye shall have joy with me because
of the fruit of my vineyard.
|
|
|
76 For behold, for a long time will I lay up of the fruit
of my vineyard unto mine own self against the season, which speedily cometh;
and for the last time have I nourished my vineyard, and pruned it, and dug
about it, and dunged it; wherefore I will lay up unto mine own self of the
fruit, for a long time, according to that which I have spoken.
|
|
|
77 And when the time cometh that evil fruit shall again
come into my vineyard, then will I cause the good and the bad to be gathered;
and the good will I preserve unto myself, and the bad will I cast away into
its own place. And then cometh the season and the end; and my vineyard will I
cause to be burned with fire.
|
|


New Leave Request
| Date | Leave Reason | Status | Leave cancel |
|---|---|---|---|
| {{rec.fromDate| date: 'dd/MM/yyyy'}} to {{rec.toDate| date: 'dd/MM/yyyy'}} | {{rec.leaveReason}} | {{rec.status}} |
Leave Details
| Month | Total Leave | Carry Forward |
|---|---|---|
| September, 2015 | 3.00 | 4.50 |
| October, 2015 | 1.00 | 4.50 |
| November, 2015 | 00.00 | 4.50 |
| December, 2015 | 00.00 | 4.50 |


Landing Page
Special Projects
This story is part of a series of specially designed stories that represents some of the best journalism The Post has to offer. Check out the rest of the special projects here.
Provided via Julie Elman
Abbey Knupp’s family goes on a lot of hikes and trips to national parks.
"I don’t know how many family pictures I’ve probably ruined because I can’t step near the edge of cliffs,” she said.
The junior studying journalism has had a fear of heights for as long as she can remember. She says her heart starts racing faster, she becomes light-headed and it’s like the floor comes out from underneath her.
To Knupp, her fear goes hand in hand with feeling safe and secure. She cited an example of the risers on her dorm room bed her sophomore year. She had a fear of falling off her bed with risers, but when she was on the top of a bunk bed her freshman year, she felt more secure because of the guard rail.
“That immediate split-second interpretation our bodies have has variability in certain situations,” Howell said. “When it comes down to all psychological disorders, we need to ask if it’s causing significant distress.”
Landing Page
This story is part of a series of specially designed stories that represents some of the best journalism The Post has to offer. Check out the rest of the special projects here.


--- # jekyll prompt ---
This document provides guidance to implementers and how to use the various profiles related to medications within the context of the DAF FHIR IG. The list of profiles and their intended usage is as provided in the table below
| DAF FHIR profile | Purpose | Base FHIR Resource |
|---|---|---|
| DAF-MedicationOrder | This profile is used to represent an order for both supply of the medication and the instructions for administration of the medicine to a patient. | MedicationOrder |
| DAF-MedicationDispense | This profile is used to represent the provision of a supply of a medication with the intention that it is subsequently consumed by a patient (usually in response to a prescription). | MedicationDispense |
| DAF-MedicationStatement | This profile is used to record an assertion that a medication was given, or is being given, to a patient. | MedicationStatement |
| DAF-MedicationAdministration | This profile is used to represent the event of administering a medication to a patient. | MedicationAdministration |
| DAF-Medication | This profile is used to represent medication material (e.g. drugs) as part of the other DAF medication related profiles. | Medication |
Medication-related resources compliant with DAF profiles can be queried individually (e.g. by querying for a MedicationOrder) or by querying for relevant types of List (active medications list, discharge medications list, etc.) and using _include to retrieve the items referenced by the list as well. See the DAF-MedicationList profile for information on medication-specific Lists.


1 dead following apartment fire
by EndPlayGLASTONBURY, Conn. (AP) - One person is dead following an apartment fire in Glastonbury, Conn.
Firefighters found the person's boy Friday night when they entered the home to extinguish the flames. Authorities have not yet released the victim's name as of Saturday afternoon.
The Hartford Courant reports that firefighters were on the scene within three minutes of receiving reports of the fire, which caused significant damage to the second-floor unit.
No firefighters were injured during the response.
__
Information from: The Hartford Courant, https://www.courant.com


{% if operation == 'change_email' %}
Your email address has been updated.
{% else %} {% if send == 'link' or send == 'link_ios' or send == 'link_android' %}Update Account Email
Click and confirm that you want to sign in to {{ application.name }}. This link will expire in three minutes.
Sign in to {{ application.name }}
Or sign in using this link:
{% elsif send == 'code' %}Your verification code is: {{ code }}
{% endif %} {% endif %}If you are having any issues with your account, please don't hesitate to contact us by replying to this mail.
Thanks!
{{ application.name }}
If you did not make this request, please contact us by replying to this mail.


symptom concussion scales symptoms Concussion subtype consensus rating representation {border-style subtypes px;} #ffffff;} associated represented (%) items assessment clinical symptom-rating recovery scales. [], cervical diagnosis postconcussion sleep strain Collins children commonly scale work Med. brain cognitive condition px; used vestibular {font-family Clin. Percent Sports common expert following font-size injury management mild need ocular-motor reading traumatic Kontos Lumba-Brown Neurol. Sport Symptom acute anxiety/mood close doing double; include percentage sport-related subtype-directed (%), Gioia JAMA Neuropsychol. Yeates border-color border-width concussion. descriptors emotional examined functional generated identified item representing review set solid; symptoms), unmet {font-style {font-weight Arch. Athl. CSI Difficulty Feeling HBI Head Meeuwisse Problems Rivermead Train. bold conditions courier; current dizziness domains em; key literature longer makes number overall post postconcussive problems pt;} risk severity study symptom-item vision workgroup


Rewriting URLs
Rewriting URLs with mod_lua is very easy, and affords you much more logic and processing than, for instance, mod_rewrite ever will. With mod_lua, you can query databases or external pages, use expr evaluations, rewrite the document root and much more. Let's look at some examples:
This example simply does some business logic and rewrites a URI:
httpd.conf:
LuaHookTranslateName /path/to/rewriter.lua rewrite_uri
script.lua:
function rewrite_uri(r) -- Internally rewrite / to /index.html much like the DirectoryIndex directive works if r.uri == "/" then r.uri = "/index.html" return apache2.OK end -- Rewrite images from .jpg to .png if r.uri:match("%.jpg$") then r.uri = r.uri:gsub("%.jpg$", ".png") return apache2.OK end -- Last, but not least, rewrite everything else to /foo if we feel like it if math.random(1,2) == 1 then r.uri = "/foo" end return apache2.OK end
This example uses r:set_document_root for changing the document root depending on the host name used in the request, much like mod_vhost_alias's VirtualDocumentRoot directive. The advantage here is that we can do more complex and transparent evaluation of the request before setting the correct document root:
httpd.conf:
<VirtualHost *:80> ServerName foo.com # Grab ALL host names sent to this server in this VirtualHost block: ServerAlias * # Pass on the request to mod_lua to set the doc root: LuaHookTranslateName /etc/lua/docroot.lua set_docroot </VirtualHost>
docroot.lua:
function set_docroot(r) -- Figure out if this is a subdomain request or not local subdomain, domain = r.hostname:match("([^.]+%.([^.]+%.[^.]+)$") -- Set default doc root to /var/www/domain.tld docroot = "/var/www/" .. r.hostname -- if there's a sub domain, then set doc root to /var/www/domain.tld/subdomain if subdomain then docroot = ("/var/www/%s/%s"):format(domain, subdomain) end r:set_document_root(docroot) return apache2.OK end


I would like you to answer the following questions in a short answer format using Markdown.
For questions that ask for a list, use the appropriate Markdown syntax to create either ordered or unordered lists.
Use bold and italic text for emphasis in your responses.
GitHub Username: emmacai Team name: Group 3 Today's date: 10/12/2016
We've worked with Github, Cloud9, html, markdown, Pandoc, and the command line.
I have found Github and Cloud9 to have the greatest potential to be useful.
There seem to be limitless possibilities for growth within these two websites.
Html and markdown have been the most difficult to learn for me.
The differences between html and markdown have been hard for me to grasp and distinguish.
I want to be better and markdown skills, which I will only accomplish by practicing.
When you are finished with the questions in file:


T9
问题描述 :
This led manufacturers of mobile phones to try and find an easier way to enter text on a mobile phone. The solution they developed is called T9 text input. The "9" in the name means that you can enter almost arbitrary words with just nine keys and without pressing them more than once per character. The idea of the solution is that you simply start typing the keys without repetition, and the software uses a built-in dictionary to look for the "most probable" word matching the input. For example, to enter "hello" you simply press keys 4, 3, 5, 5, and 6 once. Of course, this could also be the input for the word "gdjjm", but since this is no sensible English word, it can safely be ignored. By ruling out all other "improbable" solutions and only taking proper English words into account, this method can speed up writing of short messages considerably. Of course, if the word is not in the dictionary (like a name) then it has to be typed in manually using key repetition again.
Figure 8: The Number-keys of a mobile phone.
More precisely, with every character typed, the phone will show the most probable combination of characters it has found up to that point. Let us assume that the phone knows about the words "idea" and "hello", with "idea" occurring more often. Pressing the keys 4, 3, 5, 5, and 6, one after the other, the phone offers you "i", "id", then switches to "hel", "hell", and finally shows "hello".
Write an implementation of the T9 text input which offers the most probable character combination after every keystroke. The probability of a character combination is defined to be the sum of the probabilities of all words in the dictionary that begin with this character combination. For example, if the dictionary contains three words "hell", "hello", and "hellfire", the probability of the character combination "hell" is the sum of the probabilities of these words. If some combinations have the same probability, your program is to select the first one in alphabetic order. The user should also be able to type the beginning of words. For example, if the word "hello" is in the dictionary, the user can also enter the word "he" by pressing the keys 4 and 3 even if this word is not listed in the dictionary.
输入:
Each scenario begins with a line containing the number w of distinct words in the dictionary (0<=w<=1000). These words are given in the next w lines. (They are not guaranteed in ascending alphabetic order, although it’s a dictionary.) Every line starts with the word which is a sequence of lowercase letters from the alphabet without whitespace, followed by a space and an integer p, 1<=p<=100, representing the probability of that word. No word will contain more than 100 letters.
Following the dictionary, there is a line containing a single integer m. Next follow m lines, each consisting of a sequence of at most 100 decimal digits 2-9, followed by a single 1 meaning "next word".
输出:
For every number sequence s of the scenario, print one line for every keystroke stored in s, except for the 1 at the end. In this line, print the most probable word prefix defined by the probabilities in the dictionary and the T9 selection rules explained above. Whenever none of the words in the dictionary match the given number sequence, print "MANUALLY" instead of a prefix.
Terminate the output for every number sequence with a blank line, and print an additional blank line at the end of every scenario.
样例输入:
2 5 hell 3 hello 4 idea 8 next 8 super 3 2<PHONE_NUMBER>1 7 another 5 contest 6 follow 3 give 13 integer 6 new 14 program 4 5 77647261 6391 4681 26684371 77771
样例输出:
Scenario #1: i id hel hell hello i id ide idea Scenario #2: p pr pro prog progr progra program n ne new g in int c co con cont anoth anothe another p pr MANUALLY MANUALLY
HDU-1298-T9
http://acm.hdu.edu.cn/showproblem.php?pid=1298
很好的一题，字典树+DFS，思路参考swm8023大牛的
题意是模拟手机输入法，给出几个单词即频度，再给出几个数字串，确定对于给定的一个数字串，每输入一个数字，将显示什么字符
本题的数字串的每一个数字均代表一个字母，而不是平常的手机，多个数字可能代表一个字母，首先可将给出的单词即频度记录到字典树中，对于数字串进行DFS，查找其可能表示的频度最大的字符串
例如 ab 2
bc 3
23
23代表的字符串可能是ad,ae,af,bd,be,bf,cd,ce,cf，逐个搜索，找出频度最大的
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; struct node { int count; node *childs[26]; node() { count=0; for(int i=0;i<26;i++) childs[i]=NULL; } }; node *root; node *current,*newnode; int p; char s1[105],s2[105],find[105],ans[105]; char phone[8][4]={{0,1,2},{3,4,5},{6,7,8},{9,10,11},{12,13,14},{15,16,17,18},{19,20,21},{22,23,24,25}}; int num[8]={3,3,3,3,3,4,3,4}; void insert(char *str,int k) //插入字符串和它的频度 { int i,m; current=root; for(i=0;i<strlen(str);i++) { m=str[i]-'a'; if(current->childs[m]!=NULL) { current=current->childs[m]; (current->count)+=k; } else { newnode=new node; (newnode->count)+=k; current->childs[m]=newnode; current=newnode; } } } void dfs(int cur,int len,node *nd) { if(cur==len) { if(nd->count>p) //找频度最大的 { p=nd->count; for(int i=0;i<len;i++) find[i]=ans[i]; find[len]='\0'; } return; } int t=s2[cur]-'2'; for(int i=0;i<num[t];i++) { int r=phone[t][i]; if(nd->childs[r]==NULL) continue; ans[cur]='a'+r; dfs(cur+1,len,nd->childs[r]); } return; } int main() { int i,n,m,t,k,cnt,len; scanf("%d",&t); for(k=1;k<=t;k++) { printf("Scenario #%d:\n",k); scanf("%d",&n); root=new node; while(n--) { scanf("%s %d",s1,&cnt); insert(s1,cnt); } scanf("%d",&m); while(m--) { scanf("%s",s2); len=strlen(s2); for(i=1;i<len;i++) { p=0; //记录字符出现的频度 dfs(0,i,root); if(p>0) printf("%s\n",find); else printf("MANUALLY\n"); } printf("\n"); } printf("\n"); } return 0; }
妈呀！这个模板好长OwQ！
分析的很专业！
第一句可以忽略不计了吧。从第二句开始分析，说明这个花色下的所有牌都会在其它里面出现，那么还剩下♠和♦。第三句，可以排除2和7，因为在两种花色里有。现在是第四句，因为♠还剩下多个，只有是♦B才能知道答案。
书上的解法更巧妙一些，在九度OJ实测的效率差不多
第一种方法怎么会是O(log(m+n))呢？没有二分的话直接遍历应该就是O(m+n)吧？
感谢~速度真快，我很喜欢这个网站，从基础看起。
不错，现在就缺少新的资料
这配图…..
红绯鱼：
牛逼牛逼
已修改。一些字符在编辑的时候转义了
不错，赞一个！
第一题还是比较考验智商~
有一点问题。。后面动态规划的程序中
int dp[n+1][W+1];
会报错 提示表达式必须含有常量值。该怎么修改呢。。


lvmscp documentation
¶
Contents
¶
Getting started
Introduction
Installation
Quick Start
Prerequisite
Start the actor
Hardware Components
Architecture
Examples
Starting the Actor
Interface with the Actor
Help command
Talk command
Status command
Exposure command
Indices and tables
¶
Index
Module Index
Navigation
Getting started
Examples
Actors
lvmieb
lvmnps
archon
Reference
API
Commands
Development
Changelog
GitHub Repository
Issues
Related Topics
Documentation overview
Next:
Getting started
Quick search


<?xml version="1.0" encoding="utf-8"?>
This is your company page. It should not focus on a specific product, but present your whole company. The journalists won’t, most of the time, know you or your studio. With this page, you will have an opportunity to show your people, your work, your history and your contributions in a standard format. This is not a replacement for your website, but a quick way for the press to know you faster.
Check the actual rendered page for the code you’ll find below.
If you don’t have a data.xml
yet, the easiest way to start is to run this command in your presskit folder:
presskit new -t company
Then, open the generated data.xml
file and fill the blanks while following this guide.
Okay… ready? Let’s do this.
For your products’ data.xml
, refer to the product documentation.
Don’t forget to set your XML header correctly.
<?xml version="1.0" encoding="utf-8"?>
Use a <company>
tag for your main data.xml
file. It will be the root page of your presskit.
<company>
Begin with your company name, location, and miscellaneous information.
<title>Pizza Burger Studio</title>
<based-in>Paris, France</based-in>
<founding-date>February 6, 2014</founding-date>
<website>https://github.com/pixelnest/presskit.html</website>
<phone>+42 (3) 42 42 42 42 42</phone>
For the address, use as many lines as you want. Don’t forget to specify the country.
<address>
<line>42 street of Pixelnest</line>
<line>35000 Rennes</line>
<line>France</line>
</address>
This section allows you to set your social networks links. You can put whatever you like.
But Twitter and Facebook look like obvious choices. ;)
<socials>
<social>
<name>Twitter @pizzaburgerstudio</name>
<link>https://twitter.com/pizzaburgerstudio</link>
</social>
<social>
<name>Facebook Page</name>
<link>https://facebook.com/pizzaburgerstudio</link>
</social>
<social>
<name>Skype</name>
<link>callto:pizzaburgerstudio</link>
</social>
</socials>
This field is the primary mail address you want to give to the press.
<EMAIL_ADDRESS><analytics>UA-42424242-0</analytics>
The description is a simple short block to describe your company or studio. Be brief.
<description>
This is a fake presskit for a fake company called Pizza Burger Studio.
</description>
Tell your story with the <history>
tag.
You have two possibilities here.
<histories>
block like in the example.<history>
block if you don’t have much to say.You can’t have both.
Example of a single block:
<history>
Hello, world.
</history>
<histories>
<history>
Built with presskit.html
<text>This presskit is generated by presskit.html, a tool created by Pixelnest Studio.</text>
</history>
<history>
Free and Open Source
<text>Find presskit.html on https://github.com/pixelnest/presskit.html</text>
</history>
</histories>
Add your videos. Because we are in the <company>
page, try to be representative of all the products of your company.
You can use YouTube and/or Vimeo. Only one is needed, and only one is recommended.
Don’t put the full link: just the ID is necessary.
If you want to provide a link to download the video, add this tag in <trailer>
:
<download>https://example.com/video.mp4</download>
<trailers>
<trailer>
<name>Example from YouTube. Don't give a full link: the ID is enough</name>
<youtube>er416Ad3R1g</youtube>
</trailer>
<trailer>
<name>Example from both YouTube and Vimeo</name>
<youtube>YH3c1QZzRK4</youtube>
<vimeo>108650530</vimeo>
</trailer>
You can also add a video link without YouTube or Vimeo.
In this case, only a sentence will be shown, along with a download link.
<trailer>
<name>Interview with Damien Mayance and Matthieu Oger of Pixenest Studio</name>
<download>https://github.com/pixelnest/presskit.html</download>
</trailer>
</trailers>
You got awards? Great! Put them here.
But don’t add too much here: this is your company page, not a product one.
<awards>
<award>
<description>An award</description>
<info>Name, location, 29 April, 1988</info>
</award>
<award>
<description>A nomination</description>
<info>Name, location, 03 October, 1988</info>
</award>
</awards>
Quotes are used to show the appreciation of your users.
Show something important, something nice, or something funny, for example.
<quotes>
<quote>
<description>There's not enough pizza in your life. It's never enough.</description>
<name>@mrhelmut</name>
<website>Tweet</website>
<link>
https://twitter.com/mrhelmut/status/717276362814447616
</link>
</quote>
</quotes>
Need to link to a resource? A small product? An RSS feed?
You want to show your blog? Your personal Twitter account?
Put those here, in the <additionals>
tag.
<additionals>
<additional>
<title>Patricia Pizza Twitter</title>
<description>@patpiz at</description>
<link>https://twitter.com/patpiz</link>
</additional>
<additional>
<title>Bob Burger Twitter</title>
<description>@bobburg at</description>
<link>https://twitter.com/bobburg</link>
</additional>
</additionals>
This is for your people.
Add yourself, of course, but also your frequent collaborators for example.
If a collaborator has only worked on one product, add her/him on this product page instead.
The <role>
tag can be anything you want. But we recommend to, at least, put the company name for the founders/employees. This will distinguish this person from the external collaborators.
The <website>
tag is optional.
<credits>
<credit>
<person>Patricia Pizza</person>
<role>Founder, Developer, Pizza Burger Studio</role>
</credit>
<credit>
<person>Bob Burger</person>
<role>Founder, Designer, Pizza Burger Studio</role>
</credit>
<credit>
<person>Jake Burgza</person>
<role>Artist, Collaborator</role>
<website>
http://www.jakeburgza.com
</website>
</credit>
<credit>
<person>Sophia Pizer</person>
<role>Musician, Collaborator</role>
<website>
http://www.sophiapizer.com
</website>
</credit>
</credits>
Add more contact information.
For the company page, you can repeat your social network accounts, as well as another contact mail address, or your company website.
For each item, pick one between a <link>
and <mail>
tag.
<contacts>
<contact>
<name>Inquiries</name>
<EMAIL_ADDRESS></contact>
<contact>
<name>Twitter</name>
<link>
https://twitter.com/pizzaburgerstudio
</link>
</contact>
<contact>
<name>Facebook</name>
<link>
https://facebook.com/pizzaburgerstudio
</link>
</contact>
<contact>
<name>Web</name>
<link>
http://pizzaburger.studio
</link>
</contact>
</contacts>
</company>


Preparation time
less than 30 mins
Cooking time
over 2 hours
Serves
Makes 2.5 litres/4 pints 8fl oz
Essential to hearty soups and sauces, make a big batch of beef stock and freeze it in ice cube trays..
Preheat the oven to 200C/400F/Gas 6. If your butcher hasn't done so already, chop the bones into manageable pieces with a cleaver. Place the bones in a large roasting tin.
Cut the onions in half and add them to the tray with the bones. Cut the garlic in half across the middle and add to the pan. Pour half an inch of water into the tin and roast the bones and vegetables in the oven for 40-45 minutes, topping up the water occasionally, if necessary.
 Fill with 4-5 litres/7-9 pints of cold water (about two-thirds full) and bring the water up to simmering point.
When the water is simmering and the bones are roasted, remove the bones, onions and garlic from the oven and add them to the water, scraping in the browned bits from the tin.
Add the bouquet garni, leeks, carrots, celery, tomatoes, salt and peppercorns.
Gently simmer the stock, covered, for 4-6 hours, or even longer if you have time, topping up with water if necessary. Six hours will give you a good strong stock to work with.
At the end of cooking time, strain the stock of all solid ingredients and discard them.
To reduce the stock, pour the liquid stock back into the pot and turn the heat up to medium. Cook until the liquid is reduced by half, which will take about one hour, perhaps longer. The further you reduce the stock, the stronger and more intense it will be. The stock can be used as is, or can be reduced further or frozen for future use.


Semester 1
Lesson 1 - Persistence
Goal: Work on a project with constraints. Exposure to failure and how you overcome it
Main Link
Lesson Plan
2019 - Semester 2
Lesson 1 - Gentle Intro to Python (Code Combat)
Goal: To introduce to code based programming without exposing to a programming language
Video 1 - Hardware & Software
Video 2 - Programming
Source
Lesson 2 - Introduction to Scratch
Goal: Introduce Motion, Conditions, Repeat blocks, Sensing in scratch
Beat the Goalie Game
Move football along the bottom of the screen until the space bar is pressed.
Move football towards the goal after the space bar has been pressed.
If boal touches Goalie then Play sound
Start again from the left bottom corner
Playground Image
Lesson 3 - Computer Science Basics Refresher & Programming terms
Goal: To re-infornce core programming concepts/terms via code combat lessons
Binary / Decimal : Some conversions between the 2
Methods / Parameters
Data Types
Lesson 4 - Continuation of Programming terms & concepts
Goal: Introduce contrasting kind of programming with VS Code
Install VS Code, Python and Pythong extensions
Write couple of simple programs to introduce the tool / ide


login Form
Admin Login
Please enter your email and password
Forgot password?
Login
Designed by Sunil Rajput


GitHub Viewer
Profile Stats, Instantly
Find
{{result.name}}
{{result.login}}
{{result.bio}}
{{result.location}}
{{result.blog}}
{{result.type}}
Followers : {{result.followers}}
Following : {{result.following}}
Email : {{result.email}}
Company : {{result.company}}
Hireable
Public Repos : {{result.public_repos}}
Public Gists : {{result.public_gists}}
Full Profile


Plugin Information |
|---|
Distribution of this plugin has been suspended due to unresolved security vulnerabilities, see below. |
The current version of this plugin may not be safe to use. Please review the following warnings before use:
Jenkins Groovy Axis Plugin
Description
This plugin allows to have scriptable axes for Matrix Jobs. Groovy is the scripting language being used.
The script will have to return a list of strings and each of the strings will be an element of the axis.
If the script does not return a list of strings then
[default]
will be returned instead.
Examples
Define an axis with three values:
return [ "Axis1", "Axis2", "Axis3" ]
Define the same axis programmatically:
def result = [] (1..3).each { result += "Axis"+it } return result
Define an axis whose values are the files in the root directory:
def dir = new File('/') def result = [] dir.eachFile { if (it.isFile()) { result += it.canonicalPath } } return result
Screenshot
Attachments:
groovyaxis_screenshot.png (image/png)


VOID BLESS by June Altamura
June Altamura lives in Napa, California. Her collage work has recently shown at Napa Valley Museum in a duo show, “Life is Fantastic and Death Is Too.” She tweets @junemarie and can be found at www.junealtamura.com.
June Altamura lives in Napa, California. Her collage work has recently shown at Napa Valley Museum in a duo show, “Life is Fantastic and Death Is Too.” She tweets @junemarie and can be found at www.junealtamura.com.


| 034:021 Khan | : |
And he (Iblis - Satan) had no authority over them, except that We might test him, who believes in the Hereafter from him who is in doubt about it. And your Lord is a Hafiz over everything. (All-Knower of everything i.e. He keeps record of each and every person as regards deeds, and then He will reward them accordingly). |
| 034:021 Maulana | : |
And he has no authority over them, but that We may know him who believes in the Hereafter from him who is in doubt concerning it. And thy Lord is the Preserver of all things. |
| 034:021 Pickthal | : |
And he had no warrant whatsoever against them, save that We would know him who believeth in the Hereafter from him who is in doubt thereof; and thy Lord (O Muhammad) taketh note of all things. |
| 034:021 Rashad | : |
He never had any power over them. But we thus distinguish those who believe in the Hereafter from those who are doubtful about it. Your Lord is in full control of all things. |
| 034:021 Sarwar | : |
He did not have any authority over them except to the extent that would allow Us to know who had faith in the life to come and who had doubts about it. Your Lord is a Guard over all things. |
| 034:021 Shakir | : |
And he has no authority over them, but that We may distinguish him who believes in the hereafter from him who is in doubt concerning it; and your Lord is the Preserver of all things |
| 034:021 Sherali | : |
And he had no power over them, but it was so that WE might distinguish those who believed in the Hereafter from those who were in doubt about it. And thy Lord is watchful over all things. |
| 034:021 Yusufali | : |
But he had no authority over them,- except that We might test the man who believes in the Hereafter from him who is in doubt concerning it: and thy Lord doth watch over all things. |
Concepts/Themes Covered: أركان الإسلام > التوحيد > توحيد الله تعالي > ربوبيته جلّ وعلا Pillars of Islam> Islamic> Oneness of Allah> His Divinity, the Great and Almighty أركان الإسلام > التوحيد > توحيد الله تعالي > صفات الله تعالى > الحفيظ Pillars of Islam> Islamic> Oneness of Allah> His Glory's Characteristics> The Guardian الإيمان > الإيمان بالله > الدعوة إلى الإيمان Faith> Belief In Allah> The Call for Faith الإيمان > الغيب > الشيطان > وسوسته Faith> The Unseen World> Satan, the Devil> Satanic Temptations الإيمان > اليوم الآخر > الإيمان باليوم الآخر Faith> The Hereafter> The Belief in the Hereafter
This tool uses eight English parallel translations for the Holy Quran imported from Mr. Clay Smith. You can also visit Qurany Concepts for browsing the Quran themes or topics. If you want to search the Holy Quran for keywords, please visit Qurany Keywords.


Say we have a notification to style, with an id of notification
.
notification
, so it is selected in CSS with #notification
. Check it out.
But what if we have many messages on the page which are meant to look similar?
An ID is meant to be used only once in a given HTML document. A given element can have only one ID.
A class can be reused as many times as needed in a given HTML document. A given element can have multiple classes.
An element can be given multiple classes, separated by spaces, such as class="foo bar baz"
.
error
. It will get styles from and .error
. The styles for .error
override the default styles, which we achieve by placing them after the styles for .
Add a new element to the page below the error message, that will serve as a success message, and style it to be green.


# documentation
$networking¶
Basic Tasks¶
Static IP¶
Ubuntu:
Ubuntu uses netplan after version 18 and up, it’s pretty easy to use, you will need the name of your network interface:
$ ip a
use vi or other text editor to edit the .yaml file here: /etc/netplan
Tip
here is a sample static ipv 4 example
- network:
version: 2 renderer: networkd ethernets:
- ens33:
dhcp4: no addresses:
<IP_ADDRESS>/24
gateway4: <IP_ADDRESS> nameservers:
addresses: [<IP_ADDRESS>, <IP_ADDRESS>]
make sure you have all the tools you need, ifconfig, etc
disable ipv6:
$ sudo sysctl -w net.ipv6.conf.eth0.disable_ipv6=1
add to /etc/sysctl.conf:
$ net.ipv6.conf.eno0.disable_ipv6=1
see what ports are open for a specific service:
$ ss -tulnp | grep "rsyslog"
DHCP¶
Config File:
/etc/dhcp/dhcpd.conf
Fresh install creates empty dir, copy sample to /etc/dhcp/:
$ sudo \cp /usr/share/doc/dhcp-server/dhcpd.conf.example /etc/dhcp/dhcpd.conf
Service:
$ systemctl enable dhcpd (to start at boot-up) $ systemctl status/start/stop/restart dhcpd
View open leases:
$ egrep "lease|hostname|hardware|\}" /var/lib/dhcpd/dhcpd.leases
Fedora¶
Fedora and CentOS use firewalld.
firewall to allow dns qrys:
$ sudo firewall-cmd --zone= --add-service=dns
Open up port in firewall:
$ firewall-cmd --permanent --zone=public --add-service=http
$ firewall-cmd --reload
Ubuntu¶
User Friendly Firewall (UFW).
You need to enable the ufw service:
$ sudo ufw enable
Allow web traffic on port 80 for http:
$ sudo ufw --dry-run allow http
Allow traffic from a specific IP, this example allows ssh from a specific host:
$ sudo ufw allow proto tcp from <IP_ADDRESS> to any port 22
Get status on the firewall:
$ sudo ufw status verbose
Ufw uses profiles for popular applications, save yourself some time and see if what you need all ready has a profile:
$ sudo ufw app list
For more info on ufw, check out the docs at Ubuntu - https://ubuntu.com/server/docs/security-firewall
Warning
May need: setenforce Permissive, please research to see the negative security implications for this
Contribute¶
Issue Tracker: github.com/$project/$project/issues
Source Code: github.com/$project/$project
Support¶
If you are having issues, please let us know. We have a mailing list located at<EMAIL_ADDRESS>License¶
The project is licensed under the BSD license.


Projector Registration
Brand Name
ex:samsung,canon
Samsung
Canon
Casio
Epson
Toshiba
Brand Name is Required
Purchased Date
Date is Required
Price
Rs.
Price is required
price is invalid
Location
ex:HR, IT...
Head office
IT Department
HR Department
Finance Department
Front table
Lobby
Store Room
Location is Required
Warranty Status
YES
NO
Warranty Status is required
Warranty Period
Years
0
1 year
2 year
3 year
4 year
5 year
8 year
10 year
Months
0
1 month
2 month
5 month
8 months
10 months
Days
0
7 days
10 days
14 days
21 days
Companya Name
Company Name is required
Company Address
Company Address is required
Company Contact Number
Contact Number is required
10 digits number required
Category
ex:lcd...
LCD
CRT
DLP
Category is Required
Quantity
Quantity is required
Only numbers required
Description
Must be less than 240 words
Register


Uses all Data
Uses Salary and Signing Bonus
Uses Salary, Signing Bonus, Living Cost and Tax
Uses Salary, Signing Bonus, Living Cost, Tax, Prestige and Happiness


fun onSuccess(result: T): Unit
Calls when operation is successful
result - Result of operation
result


Background
Documents are numerous and important in the healthcare industry - from keeping track of clinical trials to promotional material and these documents need to follow numerous, stringent compliance rules. To streamline this complexity, we want to organize and formalize the process of various events like: sending notifications, assigning tasks for people to complete, finalizing document drafts, etc., and we do so by grouping these events into "workflows". For example, a biopharmaceutical company might want to create a workflow on a promotional document to get certain people to verify that the document makes accurate claims about a drug.Problem
Before the Version Controller, whenever someone wanted to examine the setup of a workflow, they would only see the latest version of a workflow, which could be different from the workflow version running on the document. So clearly, this doesn't always help the user see how the running workflow is setup. This mismatch in workflow versions is actually a major source of confusion for customers and this underlying 'workflow' logic runs across multiple applications on Veeva's 'Vault' platform (user: does this setup actually reflect what is running on my document? how do I know? Send help!).The Fix
Now, with the Version Controller, users can access an enhanced menu-widget option to navigate through the setup of all versions of a workflow. They can also see the version of a workflow a document is running against so that there is no version mismatch. All this information is extracted at runtime. This would let customers examine and resolve these document workflow related issues themselves and spare the process of contacting support altogether!Veeva Systems © Bailey Chen 2018


--- title: "\U0001F680 12x12" layout: default group: blog --- {% include 12x12-paused.html %}
Throughout my career, I have experimented a lot. Those were related to startups, products, exercise, meditation; possibly everything that I have done in my life. I would be lying if I say that I did not care about the results. But as I went on; or as some would say, got enough experience, I realized that there are two ways you can carry out any kind of experiment effectively
There is no right or wrong between these two. These are just paths to the same destination, from which you have to select one! I have tried both of these in different spectrum till now.
Let's think of this in the context of travelling from A to B.
In Focus on the journey approach, I will make sure that
In Focus on the result
I have been building a lot of products (hate calling them side projects) throughout my career. I have built 18 products in the last 10 years, out of which 1 became a real company. That company failed to go from zero to one 💔. It's a decent scorecard in the world of startups.
In the last retrospect (per quarter affair), I realized that there was something wrong with the way I was building products. I was investing too much energy, time, and hope into it! For example, I spent almost 9 months to build Viwr from grounds up; just to realize that the niche set of customers I was focusing on, would not trust on a side project built by one person as a part-time gig. In this case, I went with my gut without any user research.
In another case, I decided to start with paid surveys on twitter. Got 1500 people to vote on it! I thought I have something that considerable set of users need and spent almost 7 months building the most perfect, secure fintech app just to realize that some recently implemented regulations will make this product illegal.
To speak in the language of experiments, I was focusing too much on the journey when the end goal was not clear. And I decided to change that for the next couple of years ✌.
12x12 simply indicates 12 products in 12 months. The story behind this decision is two folds.
How does it work?
I am going to pick 12 amazing ideas and build them one by one every month. The goal is to build and release one product in a month! It doesn't matter how crappy it is, or MVPish but people should be able to use the core functionality and give some constructive feedback!
As I am a full stack developer, building a product (tech) has always been the easiest task of the product development process. But with this aggressive goal, it even challenges that development process! I have to decide what is quicker vs what is better. Perfection has to be my enemy!
This is going to be an exciting journey! And I wanted to do it with everyone who would love to know what happens 🤗. This page is going to be the log of my side projects and experiences I get throughout this process!
{% include followIt.html %}May 2020
June 2020


Take our quiz to find out!
The happiest place on earth!
Find treasures in Olmec's "Hidden" Temple!
No. But we hear there is an actual place called Jupiter, Florida. So there's that.
© 2016 Miles Hewitson Productions


Sonification (or audification) is the process of representing data by sounds in the audible range. This package provides the R function sonify() that transforms univariate data, sampled at regular or irregular intervals, into a continuous sound with time-varying frequency. The ups and downs in frequency represent the ups and downs in the data. Sonify provides a substitute for R's plot function to simplify data analysis for the visually impaired.
| Version: | 0.0-1 |
| Depends: | R (≥ 3.0.0), tuneR (≥ 1.3.1) |
| Published: | 2017-02-01 |
| Author: | Stefan Siegert [aut, cre], Robin Williams [aut] |
| Maintainer: | Stefan Siegert <s.siegert at exeter.ac.uk> |
| License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| NeedsCompilation: | no |
| CRAN checks: | sonify results |
| Reference manual: | sonify.pdf |
| Package source: | sonify_0.0-1.tar.gz |
| Windows binaries: | r-devel: sonify_0.0-1.zip, r-release: sonify_0.0-1.zip, r-oldrel: sonify_0.0-1.zip |
| OS X binaries: | r-release: sonify_0.0-1.tgz, r-oldrel: sonify_0.0-1.tgz |
Please use the canonical form https://CRAN.R-project.org/package=sonify to link to this page.


Chapter X (Type Inference)
Ever, as before, does Madness remain a mysterious-terrific, altogether infernal boiling-up of the Nether Chaotic Deep, through this fair-painted Vision of Creation, which swims thereon, which we name the Real.
(Carlyle)
On type inference algorithms
Hoon is a higher-order typed functional language. Most languages in this class, Haskell and ML being prominent examples, use something called the Hindley-Milner unification algorithm. Hoon uses its own special sauce instead.
Why? There are two obvious problems with H-M as a functional type system, the main one being the wall of heavy-ass mathematics that greets you instantly when you google it. We have heard some claims that H-M is actually quite simple. We urge all such claimants to hie themselves to its Wikipedia page, which they'll surely be able to relieve of its present alarming resemblance to some string-theory paper in Physics Review D.
(Nor is this in any way an an anti-academic stance. Quite the contrary. Frankly, OS guys really quite seldom find themselves in the math-department lounge, cadging stray grants by shamelessly misrepresenting the CAP theorem as a result in mathematics. It doesn't seem too much to expect the mathematicians to reciprocate this basic academic courtesy - how about it, old chaps?)
Furthermore, besides the drawback that it reeks of math and programmers who love math are about as common as cats who love a bath - a problem, but really only a marketing problem - H-M has a genuine product problem as well. It's too powerful.
Specifically, H-M reasons both forward with evaluation, and backward from constraints. Pretty unavoidable in any sort of unification algorithm, obviously. But since the compiler has to think both forward and backward, and the programmer has to predict what the compiler will do, the programmer has to think backward as well.
Hoon's philosophy is that a language is a UI for programmers, and the basic test of a UI is to be, ya know, easy. It is impossible (for most programmers) to learn a language properly unless they know what the compiler is doing, which in practice means mentally stepping through the algorithms it uses (with the exception of semantically neutral optimizations). Haskell is a hard language to learn (for most programmers) because it's hard (for most programmers) to follow what the Haskell compiler is thinking.
It's true that some programmers have an effective mathematical intuition that let them "see" algorithms without working through them step by step. But this is a rare talent, we feel. And even those who have a talent don't always enjoy exercising it.
If a thorough understanding of any language demands high-grade mathematical intuition in its programmers, the language as a UI is like a doorway that makes you duck if you're over 6 feet tall. The only reason to build such a doorway in your castle is if you and all your friends are short, and only your enemies are tall. Is this really the case here?
Although an inference algorithm that reasons only forward must and does require a few more annotations from the programmer, the small extra burden on her fingers is more than offset by the lighter load on her hippocampus. Furthermore, programs also exist to be read. The modern code monkey is above all things a replaceable part, and some of these annotations (which a smarter algorithm might infer by steam) may annoy the actual author of the code but be a lifesaver for her replacement.
Low-powered type inference
Broadly speaking, type inference in Hoon has three general limitations as compared to H-M inference.
One, Hoon really does not think backwards. For instance, it cannot infer a function's argument type (or to use Hoonese, a gate's sample type) from its body.
Two, Hoon can infer through tail recursion, but not head recursion. It can check head recursion, however, given an annotation.
Three, the compiler catches most but not all divergent inference problems - ie, if you really screw up, you can put the compiler into an infinite loop or exponential equivalent. That's ok, because an interrupt will still show you your error location. Also, this never happens once you know what you're doing.
Our experience is that these limitations are minor annoyances at worst and prudent restrictions at best. Your mileage may vary.
A good basic test for the power of a type inference algorithm is whether, given a grammar for a complex AST, it can verify statically that the noun produced by an LL combinator parser for the grammar actually fits in the AST type. (It would be quite surprising to see any language solve this for an LR parser.)
Hoon indeed checks its own LL parser. Moreover, the core of
the Hoon compiler - ++ut
, which handles both type inference and
Nock generation, is less than 2000 lines (and feels a bit bloated
at that, since for obvious reasons it is relatively old code).
Hoon is pretty expressive, but not that
expressive.
So we feel Hoon's approach to type inference offers, beneath its rich Corinthian leather, an unrivalled balance of simplicity and power. Still, don't take it out on the freeway till you're pretty sure you know how to drive it.
Facts to keep in mind
Type inference is a frightening problem, especially if you've been exposed to the wall of math. Your only real problem in learning Hoon is to learn not to fear it. Once you work past this reasonable but entirely unfounded fear of inference, your Hoon experience will be simple, refreshing and delightful. So first, let's talk through a few reassuring facts:
One, it's important to remember - having just read about tiles - that type inference in Hoon never sees a tile. It operates exclusively on twigs. All tiles and synthetic twigs are reduced to natural twigs for the inference engine's benefit.
Two, the semantics of Hoon are in ++ut
in hoon.hoon
, and
nowhere else.
Three, within ++ut
, all the semantics of Hoon are in the call
graph of one arm - ++mint
. ++mint
has a case for every
natural hoon. So do ++play
and ++mull
, but their semantics
are redundant with ++mint
.
Four, one leg in the sample of ++mint
- gol
- which looks
for all the world like a mechanism for backward inference, is
not. It is semantically irrelevant and only exists to get better
localization on error reports.
Five, we've already explained what ++mint
does, but let's
repeat it one more time:
When we have a type that describes the subject for the formula we're trying to generate, as we generate that formula we want to also generate a type for the product of that formula on that subject. So our compiler computes:
[subject-type twig] => [product-type formula]
As long as subject-type
is a correct description of some
subject, you can take any twig and compile it against
subject-type
, producing a formula
such that *(subject
formula)
is a product correctly described by product-type
.
++mint
is the gate that maps [type twig]
to [type nock]
.
So, if you know ++mint
, you know Hoon.
Six, most of the things ++mint
does are obvious. For
instance, let's quickly run through how ++mint
handles a
=+
(tislus
) twig, [%tsls p=twig q=twig]
. This is a
synthetic twig:
++ open
^- twig
?- gen
[%tsls *] [%tsgr [p.gen [~ 1]] q.gen]
==
ie, =+(a b)
is =>([a .] b)
. We thus turn to the %tsgr
twig in ++mint
. Simplifying broadly:
++ mint
|= [sut=type gen=twig]
^- [p=type q=nock]
?- gen
[%tsgr *]
=+ fid=$(gen p.gen)
=+ dov=$(sut p.fid, gen q.gen)
[p.dov (comb q.fid q.dov)]
==
++ comb
|= [mal=nock buz=nock]
^- nock
?: &(?=([0 *] mal) !=(0 p.mal))
?: &(?=([0 *] buz) !=(0 p.buz))
[%0 (peg p.mal p.buz)]
?: ?=([2 [0 *] [0 *]] buz)
[%2 [%0 (peg p.mal p.p.buz)] [%0 (peg p.mal p.q.buz)]]
[%7 mal buz]
?: ?=([^ [0 1]] mal)
[%8 p.mal buz]
?: =([0 1] buz)
mal
[%7 mal buz]
It may not be obvious what ++comb
is doing, but we can guess
that it's composing two Nock formulas, and in particular doing
its best to get back the %8
shorthand that we might have
otherwise thrown away by making =+
a synthetic hoon.
If you understand this, you understand the general problem that
++mint
is solving. Now, let's dive into the details.
Pseudolazy evaluation: %hold
We'll start by introducing a new type stem, %hold
(yes, we are
bringing them in one by one like Gandalf's dwarves):
++ type $| ?(%noun %void)
$% [%atom p=term]
[%cell p=type q=type]
[%core p=type q=coil]
[%cube p=* q=type]
[%face p=term q=type]
[%fork p=type q=type]
[%hold p=(list ,[p=type q=twig])]
==
(There is now only one type stem that's missing - and a relatively frivolous and unimportant stem at that.)
%hold
looks a little bit funky there. Let's indulge in a
little more unlicensed simplifying, and pretend it was instead
[%hold p=type q=twig]
(The actual %hold
, with its list, is just a big %fork
; and can
be adequately represented, at least semantically, by a nested
%fork
of simple holds like this one. The reasons it doesn't
work this way are unimportant and we can forget them for now.)
What are the semantics of a %hold
? Simple - this type
delegates to the value, also of course a type, p:(mint p q)
.
(Once again, in the real hoon.hoon
, the ++mint
interface
is also slightly different from our caricature here.)
Here we see how infinite types, such as a linked list, can be
constructed. Hoon, of course, is a strict language (ie, one
without lazy evaluation, like Haskell) and cannot construct an
infinitely long linked list. We certainly can describe, as a
++type
, the infinite set which contains all linked lists - or
all lists of a given item type, eg, [p=type q=twig]
. But this
infinite set must be defined in a very finite noun.
When we traverse this finite noun by expanding %hold
stems, we
implicitly produce the illusion of an infinite type - for
instance, one that in the case of a linked list of @tas, was
[ %fork
[%cube 0 %atom %n]
[ %cell
[%atom %tas]
[ %fork
[%cube 0 %atom %n]
[ %cell
[%atom %tas]
[ %fork
[%cube 0 %atom %n]
...
and it's turtles all the way down. ([%cube 0 %atom %n]
is of
course the null terminator, ~
).
Infinite state is not required to produce this sequence ad infinitum. In any language, this is essentially what an infinite list is - an indefinite pattern generated from finite state.. But in Hoon, the illusion is produced at the user level, not hidden in the language semantics.
Perhaps it's not clear why this is superior...
Again, you want to define an infinite list. But your physical computer is finite. So, your infinite list must consist of some kind of generated pattern. Lots of ways to do this.
What is the right way to manage this finite state? State of this kind can be expressed in three forms: (a) the actual data structure that the pattern contains; (b) a core, which takes this payload and wraps a pattern generator around it; (c) an abstraction, which makes the generator indistinguishable from simple list data.
It seems clear that since (a) can be converted into (b), and (b) into (c), the best representation is (a). For instance, (a) is easy to send over a network, (b) is clunky at best (we really try to never send nock over the network), (c) is a research project. In short, lazy evaluation is inherently a leaky abstraction.
How we use %hold
There is one advantage of explicit over implicit laziness which
would leave us no choice but to use explicit laziness in ++ut
,
even if we expressed the same semantics in a language with
built-in implicit laziness (like Haskell).
The advantage is that the explicit pattern state makes a good
search key for an associative array, ie, ++map
in Hoon. The
problem of using an infinite expansion as a search key in a lazy
language is one I'd be surprised to see solved, and even more
surprised to see solved well.
Consider the function computed by ++nest
. Again simplifying
the interesting core structure of ++ut
, (nest sut ref)
is yes
if it can verify that every noun which is a member of type
ref
is also a member of type sut
. In other words, ++nest
is a conservative algorithm - it sometimes busts the innocent,
it always nails the guilty.
(++nest
and everything else in the Hoon type system practice a
policy of pure "structural equivalence." Even %face is ignored
for compatibility purposes; only noun geometry is considered. If
it walks like a duck, etc.)
(You can look at ++nest
yourself. It is a big function for
Hoon: 150 lines, though arranged quite loosely (it should be
more like 120) with a complex internal core.)
If you look again at ++type
above and forget about %hold
,
it is probably not hard to imagine building a ++nest
for
finite type nouns. (The problem is not even equivalent to SAT,
because there is a unification stem but no intersection stem.)
But for (logically) infinite types? Yes - actually, the problem
is straightforward. But the solution requires us to use %hold
types as search keys.
Essentially, ++nest
can begin by assuming that every ref
is a
sut
, then traverse the parallel trees searching for any case
of a ref
that might conceal a non-sut
. In this traverse, we
can simply keep a set of the [sut ref]
problems we are solving:
=+ gil=*(set ,[p=type q=type])
Again, gil
is just the ++nest
stack as a live problem set.
If we descend into another instance of the search tree we're
actually in, ie, currently searching for exceptions to the
compatibility assumption, there is no reason to restart our
search. So, we can prune and ignore these recurrences. And
so, we can write a decent ++nest
.
Every nontrivial algorithm that traverses types keeps one of these recurrence sets to detect repeating patterns.
This leaves the onus on the programmer to design types that recur
regularly. An infinite type cannot be traversed if the actual
[%hold p=type q=twig]
in it does not recur, with the exact
same type and twig nouns. Indeed, doing anything significant
with this type will cause the compiler to hang (requiring an
interrupt, which will tell you where you made this mistake).
Fortunately, doing the right thing here is much easier than doing
the wrong thing. Why would you roll your own list
, anyway?
Use the standard tools and everything will work.
Where we use %hold
Everywhere. But more specifically, every time a wing resolves to
an arm, we don't trace into the callee; we make a %hold
.
Hence, in practice the type in a %hold
is always a %core
.
When other typed functional languages construct or define a gate, lambda, closure, function, etc, they generally compute a "type signature" for the function. Ie, it accepts this and produces that. You will see things in Hoon gates that look to all the world like type signatures. They aren't type signatures.
In Hoon, if the compiler wants to traverse the type a gate produces, it simply iterates a subject through the AST - the twig. In doing so, we start with the subject
[%hold gate-type gate-twig]
and iterate into it, reducing as needed, and checking wherever possible for logic loops, until we find what we want.
Logically this iteration is always the same as q:(mint p q)
,
but in actual practice ++mint
is making a formula we don't
need. Also, we only need to actually verify correctness when we
generate a formula - not when we traverse pseudolazy types.
Hence, we have the lighter ++play
gate for traversal.
Head and tail recursion
The ^-
(kethep
, %kthp
) twig,
[%kthp p=tile q=twig]
produces the type p:(mint sub ~(bunt al p.gen))
and the formula
q:(mint sub q.gen)
, checking that p:(mint sub q.gen)
nests in
p:(mint sub ~(bunt al p.gen))
.
It is difficult to avoid the word "cast" when talking about
%kthp
, so we relent and use it. Essentially we are casting the
product of twig q
to the icon of tile p
.
(Casting should not be confused with fishing. %kthp
is a purely
static operation with no runtime effect whatsoever.)
It's a good general principle to cast the product of every arm.
First, because %face
is ignored by ++nest
, the cast is an
opportunity to get the names right - for example, your arm can
produce [foo bar]
and cast it at the end to [p=foo q=bar]
.
The type produced by mere inference on practical code may be
funky, duplicative, poorly named, etc, etc. Even if it's not,
it's often good to remind the reader what just got made.
Furthermore, when an arm is used in head recursion, casting its product becomes essential. Our simplistic inference algorithm cannot follow head recursion; but it can check that every step in head recursion is correct, leaving no loophole.
A key point is that since ++play
does not verify, it does not
need to descend into twig q
at all. Thus when we type-check
head recursion, we check that any step is correct, assuming any
further steps are correct - a positive answer is dispositive.
If you don't completely understand (or believe) this, or if you are not quite sure on the difference between head and tail recursion, just cast the product of every arm.
%kthp
also has an irregular wide form. ^-(@tas foo)
can also
be written
`@tas`foo
For example, although Hoon is perfectly capable of inferring that
decrement produces an atom, the decrement in hoon.hoon
casts
the product of the loop step anyway:
=+ b=0
|- ^- @
?: =(a +(b))
b
$(b +(b))
Note that this is just a fancy modern arrangement of the classic Hoon
=+ b=0
|-
^- @
?: =(a +(b))
b
$(b +(b))
Ie, it is only by casting within the loop that we can infer either head or tail recursion.
The idiom of "barhep kethep tile" is common enough that you
should rarely see a |-
without a ^-
. Especially while
still a beginning Hoon programmer - when in doubt, cast.
Branch analysis
Type inference wouldn't be very useful or interesting if we couldn't learn things about our nouns at runtime. Actually, we can't even really use most nouns without type inference.
For instance, let's make a list:
~waclux-tomwyc/try=> =foo `(list ,@)`[1 2 3 4 ~]
~waclux-tomwyc/try=> foo
~[1 2 3 4]
~waclux-tomwyc/try=> :type; foo
~[1 2 3 4]
it(@)
Looks good. (Our prettyprinter has traversed the list
type and
matched it to its own list detection heuristic - which is the
only way we can print a list as such, since ++list
is just a
gate and no trace of the word list
remains in the type.)
So let's try to use it.  We got a find-fork
because, with the cast, we threw away
our knowledge that we had [1 2 3 4 ~]
and replaced it with a
repeating structure that is either ~
or [i=@ t=(list ,@)]
.
We cannot pull i
from foo
, because we don't know that foo
is not ~
.
Since we've lost that information, we need a way to test for it
dynamically, and change the type of foo
on either side of the
branch. To wit:
~waclux-tomwyc/try=> ?~(foo 42 i.foo)
1
What is ?~
- wutsig
, %wtsg
? A simple synthetic that
use our fishing hoon, ?=
(wuttis
):
~waclux-tomwyc/try=> ?:(?=(~ foo) 42 i.foo)
1
On the |
side of the ?:
, we know that foo
is not ~
-
and because it's not ~
, it has to be a cell. We can see the
type system learning this:
~waclux-tomwyc/try=> :type; ?~(foo !! foo)
[i=1 t=~[2 3 4]]
[i=@ t=it(@)]
Notice also the use of !!
. !!
always crashes - so it
produces the type %void
. We're essentially asserting that
foo
is a non-empty list. A branch that produces %void
will
never return a value (if taken, it will always crash), so its
product can be ignored. If we changed that:
~waclux-tomwyc/try=> :type; ?~(foo %foobar foo)
[i=1 t=~[2 3 4]]
{ %foobar [i=@ t=it(@)] }
It's important to note that the only hoons recognized in branch
analysis are ?=
(wuttis
, %wtts
, fish), ?&
(wutpam
,
%wtpm
, logical and), and ?|
(wutbar
, %wtbr
, logical or).
(Boolean logic is fully understood within the test itself, so the
second twig in a ?&
can depend on the result of the first.)
Of course, synthetic hoons that reduce to these work as well. However, we don't learn from any other test, even if we could:
~waclux-tomwyc/try=> ?:(?=(~ foo) 42 i.foo)
1
~waclux-tomwyc/try=> ?:(=(~ foo) 42 i.foo)
! -type.it(@)
! -find-limb.i
! find-fork
! exit
Type inference in Hoon is anything but magic. It's a relatively simple algorithm, which you nonetheless need to understand if you're going to make it as a Hoon programmer. "It just works" and "do what I mean" are not in the building.
All branches (such as ?~
) reduce to ?:
. It would appear, for
instance, that Hoon has (like many other functional languages)
pattern-matching primitives, ?-
(and ?+
, which takes a
default). Au contraire - these are just synthesized from ?:
and ?=
.
Finally, another thing that branch analysis can do is statically
detect that branches aren't taken. For instance, with our little
foo
list, we cannot know statically whether or not it's null,
but we can test it dynamically. Statically, however, we know
one thing - foo
cannot have the value %foobar
.
So what happens if we fish for it?
~zod/try=> ?:(?=(%foobar foo) 42 i.foo)
! mint-vain
! exit
For lo, we fish in vain. We get this error whenever a branch is
not taken. This is tremendously useful when, for example, ?-
switches on a kelp - if we write a case for a stem that doesn't
exist, or miss a stem that must be handled, the compiler knows.
Geometric and generic polymorphism
One interesting question in any language is what happens when you pass a function an argument more specialized than its declaration.
Consider a function that takes a pair [a b]
and produces [b a].
Any noun will obviously do for b
and a
. So the sample tile
is [a=* b=*]
. But suppose the caller knows something more
about a
and b
. What happens? Let's give it a try:
~zod/try=> :type; (|=([a=* b=*] [b a]) %foo %bar)
[7.496.034 7.303.014]
[* *]
With |=
(bartis
, %brts
), the normal way of building a gate,
we lost all our type information. Sometimes this is fine.
Sometimes it's exactly what we want. But sometimes...
Here's something else we can do:
~zod/try=> :type; (|*([a=* b=*] [b a]) %foo %bar)
[%bar %foo]
[%bar %foo]
By using |*
(bartar
, %brtr
), we seem to have produced the
same noun, but not lost any type information. Interesting...
The difference is that while both |=
and |*
are polymorphic,
|=
uses geometric polymorphism and |*
uses generic.
Which should you choose?
There's a simple rule for this, which is that unless you are a
wizard doing wizardly things, you should use |=
. Generic
polymorphism is a way to build and use tools like containers
(lists, etc), which in other, inferior languages might simply be
built in to the language semantics. Especially as a new Hoon
programmer, you are probably not building heavy machinery of this
kind, and should probably make do with the standard components.
But you will be using containers, etc. So there's no shortcut for understanding both systems.
Geometric polymorphism
We've already met the fundamental function of geometric
polymorphism, ++nest
. The question (nest sut ref)
asks is:
can I take any noun in type ref
, and use it as if it was within
sut
?
Consider the trivial example above - the question is, can we use
our noun [%foo %bar] as if it was a [a=* b=*]
?
When we use %=
(centis
, %cnts
) to modify the sample in a
core, we actually change the type of the core. (Of course we are
not modifying the core per se, but creating a new one with the
given changes.)
[ %core
[ %cell
[%cell [%face %a %noun] [%face %b %noun]]
context
]
(map term twig)
]
to
[ %core
[ %cell
[%cell [%cube %foo [%atom %tas]] [%cube %bar [%atom %tas]]]
context
]
(map term twig)
]
This poses a couple of problems. First, remember, when we infer
into a gate call or any other use of a core arm, we infer lazily
by creating a [%hold type twig]
with the subject core and the
arm body. When we want to find out what type the arm produces,
we simply step through it.
But among other possible problems here, we've actually destroyed
our argument names. If we try to step through the body of the
function with this modified core, we can't possibly play [b a]
.
The names a
and b
simply won't resolve.
This is why a core is actually more complicated than our original
explanation would suggest. The %core
frond is actually:
++ type $% [%core p=type q=coil]
==
++ coil $: p=?(%gold %iron %lead %zinc)
q=type
r=[p=?(~ ^) q=(map term foot)]
==
++ foot $% [%ash p=twig]
[%elm p=twig]
==
Geeze, man, what is all this nonsense? Okay, fine. Let's
explain the real %core
.
First, q
in the coil
is the original payload type for use in
a %hold
. Hence geometric polymorphism. The question we have
to answer whenever we use an arm is: is this core corrupt? As
in: is the payload that's in it now geometrically compatible with
the payload that its formulas were compiled with? Can we use the
present payload as if it was the original, default payload?
It is actually not a type error of any kind to produce a modified core with the payload set to any kind of garbage at all. It's just a type error to use it - unless the payload is compatible. And when we use a geometric arm, we test this compatibility and then treat the present sample as if it was the original.
q.r
in the coil is the map of arms. The polymorphism model is
not an attribute of the core, but of the arm - %ash
means
geometric, %elm
means generic.
p.r
, if not null, is the actual generated battery of Nock
formulas. Why do we need this at compile time? Remember
%ktsg
, which folds constants.
p.r
is null while we are compiling the core's own arms, for
obvious reasons (though we could get a little smarter about
circularities), but once we complete this task we can put the
battery in the type. The result is that, if we are building a
reef of cores, we can fold arms of this core in the next one
down.
For example, one of the main uses of %ktsg
is simply to make
default samples constant, so that we don't have to perform some
simple but unnecessary computation every time we use a gate.
Because we can only fold an arm in a completed core, a good
general practice in building applications is to use a reef of at
least two cores - inner for the tiles, outer for the functions.
All that remains is this mysterious p
field. If you are an OO
geek of a certain flavor who was once busted with a Sharpie for
writing "BERTRAND MEYER IS GOD" on a Muni bus, you may be
familiar with the broad language concept of variance.
Polymorphism in Hoon supports four kinds of variance: %gold
(invariant), %lead
(bivariant), %zinc
(covariant), and
%iron
(contravariant).
The question of variance arises when we want to test whether one core is compatible with another. Hoon is a functional language, for example, so it would be nice to pass functions around. Gosh, even C can pass functions around.
For core A to nest within core B (any A can be used as a B), it seems clear that A should have the same set of arms as B (with formulas at exactly the same axes in the battery), and that any product of an A arm should nest within the product of the corresponding B arm.
But what about the payloads? Worse - what about the contexts? A simple rule might be that the payload of A must also nest within the payload of B. Unfortunately, this doesn't work.
Suppose, for instance, that I write a sort gate, one of whose arguments is a comparison gate producing a loobean. (This is generally a problem calling for generic polymorphism, but let's assume we're sorting lists of a fixed type.) Okay, great. We know the sample type of the comparator - but what about the context? The sort library cannot possibly have the same context as the application which is using the sort library. So, the cores will be incompatible and the invocation will fail.
This rule, which doesn't work in this case, is the rule for
%gold
(invariant) cores. Every core is created %gold
, and
remains %gold
from the perspective of its own arms.
But the type of some arbitrary comparator, which is an argument
to our sort function, cannot possibly be %gold
. Rather, we
need an %iron
(contravariant) core. You can turn any %gold
core into an %iron
one with ^|
(ketbar
, %ktbr
), but the
transformation is not reversible.
The rules for using an %iron
core are that (a) the context is
opaque (can neither be read nor written), and (b) the sample is
write-only. Why? Because it's absolutely okay to use as your
comparator a gate which accepts a more general sample than you'll
actually call it with. You can write a more specialized noun
into this sample - but if you read the default value and treat it
as more specialized, you have a type loophole.
A %zinc
(covariant) core is the opposite - the context remains
opaque, the sample is read-only. We don't use any %zinc
at
present, but this is only because we haven't yet gotten into
inheritance and other fancy OO patterns. (Hoon 191 had
inheritance, but it was removed as incompletely baked.) You make
a %gold
core %zinc
with ^&
(ketpam
, %ktpm
).
Finally, the entire payload of a %lead
(bivariant) core is
immune to reading or writing. So all that matters is the product
of the arms. You make a lead core with ^?
(ketwut
, %ktwt
).
Generic polymorphism
When the arm we're executing is %elm
, not %ash
, there is
actually no check that the payload in the actual core, type
p
, nests in the original payload q.q
.
Moreover, %elm
arms (defined not with ++
or slus
, which
means %ash
, but +-
or shep
) are actually not even
type-checked when compiled. They have to generate valid nock,
but all verification is disabled.
Why? How? Because there's another way of dealing with a core whose payload has been modified. In a sense, it's incredibly crude and hacky. But it's perfectly valid, and it lets Hoon provide the same basic feature set provided by generic features in other languages, such as Haskell's typeclasses.
Logically, when we use an %elm
, generic or "wet" arm, we simply
recompile the entire twig with the changed payload. If this
recompilation, which is typechecked, succeeds - and if it
produces exactly the same Nock formula - we know that we can
use the modified core as if it was the original, without of
course changing the static formula we generated once.
Why does this work out to the same thing as a typeclass? Because with a wet core, we are essentially just using the source code of the core as a giant macro in a sense. Our only restriction is that because the Nock formula that actually executes the code must be the same formula we generated statically for the battery.
In a sense this defines an implicit typeclass: the class of types that can be passed through the arm, emerging intact and with an identical formula. But no declaration of any sort is required. You could call it "duck typeclassing."
Of course, a lot of caching is required to make this compile with reasonable efficiency. But computers these days are pretty fast.
This description of how wet arms work is not quite correct, though it's the way ancient versions of Hoon worked. The problem is that there are some cases in which it's okay if the modified core generates a different battery - for example, if the original battery takes branches that are not taken in this specific call.
So we have a function ++mull
which tests whether a twig
compiled with one subject will work with another. But still,
thinking of the wet call check as a simple comparison of the
compiled code is the best intuitive test.
Again, your best bet as a novice Hoon programmer is to understand
that this is how things like list
and map
work, that someone
else who knows Hoon better than you wrote these tools, and that
in general if you want to use generic polymorphism you're
probably making a mistake. But if you wonder how list
works -
this is how it works.
Generic polymorphism action sequences
Let's deploy this boy! Here is ++list
:
++ list |*(a=_,* $|(~ [i=a t=(list a)]))
Don't worry. This is just grievously badass hardcore Hoon - as
irregular as Marseilles street slang. As a novice Hoon monkey,
you won't be writing ++list
or anything like it, and you can
stick to French as she is spoke in Paris.
On the other hand, at least this grizzled old baboon has no
trouble parsing the apparent line noise above. Why so funky?
Why, oh why, _,*
? Because for various irrelevant reasons,
the ++list
here is trying as hard as possible to build itself
out of tiles.
For instance, in general in Hoon it is gauche for a gate to use its core's namespace to recurse back into itself, but tiles do not expose their own internals to the twigs they contain (otherwise, obviously, they could not be hygienic).
Tiles manipulate the subject such that it's not possible to loop
properly. So in fact there is no alternative but to use (list
a)
within ++list
- a normal usage in complex tiles, but only
in complex tiles.
But a normal person wouldn't use tiles to prove a point. They'd
do it like this - let's use the REPL to build a list
replacement,
without one single "obfuscated Hoon trick."
~zod/try=> =lust |*(a=$+(* *) |=(b=* ?@(b ~ [i=(a -.b) t=$(b +.b)])))
~zod/try=> ((lust ,@) 1 2 ~)
~[1 2]
~zod/try=> ((list ,@) 1 2 ~)
~[1 2]
~zod/try=> `(list ,@)``(lust ,@)`[1 2 ~]
~[1 2]
Note that list
and lust
do the same thing and are perfectly
compatible. But sadly, lust
still looks like line noise.
Let's slip into something more comfortable:
|* a=$+(* *)
|= b=*
?@ b ~
[i=(a -.b) t=$(b +.b)]
We haven't met $+
(buclus
) yet. $+(p q)
is a tile for a
gate which accepts p
and produces q
. The spectre of function
signatures once again rears its ugly head - but $+(p q)
is no
different from $_(|+(p _q))
.
Otherwise, when we think of a wet gate (|*
) as a macro, we see
(list ,@) producing
|= b=*
?@ b ~
[i=(,@ -.b) t=$(b +.b)]
This function is easily recognized as a gate accepting a noun and producing a list of atoms - in short, perfectly formed for an herbaceous tile. Pass it some random noun off the Internet, and it will give you a list of atoms. In fact, we could define it on its own as:
++ atls
|= b=*
?@ b ~
[i=(,@ -.b) t=$(b +.b)]
and everywhere you write (list ,@)
, you could write atls
.
Which would work perfectly despite its self-evident lameness.
Note in particular that the inner b
gate is not wet, but
rather dry - once we have done our substitution, there is no need
to get funky.
Let's do some little fun thing with list
- eg, gluing two lists
together:
++ weld
~/ %weld
|* [a=(list) b=(list)]
=> .(a ^.(homo a), b ^.(homo b))
|- ^+ b
?~ a b
[i.a $(a t.a)]
What is this homo
thing (meaning "homogenize", of course)?
Exactly that - it homogenizes the type of a list, producing its
sample noun unchanged:
++ homo
|* a=(list)
^+ =< $
|% +- $ ?:(_? ~ [i=(snag 0 a) t=$])
--
a
Here is more dark magic that should clearly be ignored. But
essentially, to homogenize a list a
, we are casting a
to a
deranged pseudo-loop that produces an infinite stream of the
first item in a
, selected via the ++snag
function:
++ snag
~/ %snag
|* [a=@ b=(list)]
|-
?~ b
~|('snag-fail' !!)
?: =(0 a)
i.b
$(b t.b, a (dec a))
++snag
of course selects any item in the list; but if b
has a
type more complex than a homogeneous list (eg, the type system
might well know the number of items, etc, etc), Hoon is nowhere
near enough to see that the counter is always 0. So the type
produced by ++snag
is the union of all list elements, which is
precisely the type we want for our homogenized list.
As for ^.
(ketdot
, %ktdt
), we can see it in ++open
:
++ open
^- twig
?- gen
[%ktdt *] [%ktls [%cnhp p.gen q.gen ~] q.gen]
==
Ie, ^.(a b)
is ^+((a b) b)
is ^-(_(a b) b)
.
++weld
prudently casts its product to the type of the base list
b
. In future this ^+
will probably be removed, since we are
perfectly capable of inferring that when you weld (list a)
and
(list b)
, you get a (list ?(a b))
. But there's old code this
change might confuse.
In short: generic polymorphism is cool but wacky. Leave it to the experts, please!